我来自(最近)来自C#,我习惯于实例化这样的对象:
Phone myPhone = new Phone();
简单地写
Phone myPhone;
基本上为一个类创建了一个持有者,但它还没有被初始化。
现在我正在用C ++编写一个小类,我遇到了问题。这是伪代码:
Phone myPhone;
void Initialise()
{
myPhone = new Phone();
}
void DoStuff()
{
myPhone.RingaDingDong();
{
实际上这有点误导,因为上面的代码是我想要的,因为我希望能够将我的所有初始化代码放到一个整洁的地方。我的问题是在C ++中初始化内部的行是不必要的,因为在此之前,已经创建了一个新实例并由第一行初始化。另一方面,如果我将第一行放在Initialise()中,我就无法在DoStuff中访问它。它超出了范围,(更不用说在C ++中使用'new'或不使用'之间的区别)。如何为类变量创建一个简单的持有者,以便我可以在一个地方初始化它,并在另一个地方访问它?或者我得到了一些根本错误的东西?
提前致谢!
答案 0 :(得分:2)
您可以在指针上使用new运算符:
Phone *myPhone;
void Initialise()
{
myPhone = new Phone();
}
void DoStuff()
{
myPhone->RingaDingDong();
}
在访问*
时,仅有两项更改是myPhone
声明中添加的->
和.
而非RinaDingDong()
。您还必须释放它,因为new
正在分配内存:
void destroy()
{
delete myPhone;
}
请注意,如果您这样做,myPhone
将成为指向Phone
而非实际Phone
的指针。
答案 1 :(得分:2)
如果您的Phone构造函数没有参数,那么您的生活非常简单 - 您无需在Initialize方法中新建手机。在创建对象并为您管理生命周期时,将为您创建它。
如果需要获取参数,并且它没有Initialize()方法或某些set方法,那么您可能需要使用指针(有时可以为null)并使Initialize()调用new并传递这些参数。您的其他代码需要在使用之前检查指针是否为空。您还需要管理生命周期(通过编写大3)或使用智能指针,如C ++ 11中的shared_ptr。这不应该是你的首选。
答案 2 :(得分:0)
我认为你需要在指针上刷一点。 你可以用指针做什么。
我的问题是在C ++中初始化内部的行是不必要的,因为在此之前,已经创建了一个新实例并由第一行初始化。
这是不正确的。您提供的评论仅适用于构造函数。从您的puesdo代码,函数initialize
是一个全局函数,不是类的成员函数。
另一方面,如果我将第一行放在Initialise()中,我就无法在DoStuff中访问它。它超出了范围,(更不用说在C ++中使用'new'或不使用'之间的区别)。
请参阅有关指针的任何书籍,您可以使用全局指针并使用new
进行初始化。这可以在doStuff中使用
答案 3 :(得分:0)
如果你来自C#,你知道你有两种类型的对象:class和struct。
通过引用复制,分配和传递类。因此,他们使用的是参考语义。该类也在堆中分配(使用new)。
struct正在实现一个值复制语义。 struct在堆栈上分配(int,double和其他内置类型是struct)。你不能处理struct polymorphicaly。
在C ++中,你没有这个区别。类和结构本质上是相同的(默认访问级别的一部分)。确定复制语义不是类的声明,而是实例对类的声明。
如果创建指针,则行为与c#中的类非常相似。如果创建对象,则语义将类似于c#中的结构。
C ++也有参考,你应该阅读指针和引用之间的区别。
答案 4 :(得分:0)
凯特格雷戈里的答案是正确的,但我想详细说明一下。 C ++中更强大的一个想法是堆栈分配的对象由其包含的范围所拥有。例如,如果你想写一个包含手机的课程,你只需写下:
class Secretary {
Phone myPhone;
};
现在每次创建一个秘书时,都会使用默认构造函数自动初始化Phone对象。更重要的是,每当一个Secret对象被销毁时,它所包含的Phone对象也会被销毁。如果要为Phone使用不同的构造函数,可以在Secretary的构造函数中使用初始化列表:
class Secretary {
private: // members
Phone myPhone;
Phone myCellPhone;
public: // methods
Secretary() : myPhone("phone constructor", 12, " args") {}
};
在这种情况下,myPhone使用其3参数构造函数初始化,并且myCellPhone像往常一样使用其默认构造函数进行初始化。