2011-09-23 104 views
1

我来了(最近):C++对象实例化和范围

Phone myPhone = new Phone(); 

简单地写

Phone myPhone; 

实质上创造了一个支架一个班级,但尚未初始化。

现在我正在写一个C++的小班,我有一个问题。下面是伪代码:

Phone myPhone; 

void Initialise() 
{ 
    myPhone = new Phone(); 
} 

void DoStuff() 
{ 
    myPhone.RingaDingDong(); 
{ 

事实上,这是因为上面的代码有点误导是什么,我想有,因为我希望能够把我所有的初始化代码为许多东西到一个整洁的地方。我的问题是在C++中初始化内部的行是不必要的,因为在这之前,一个新的实例已经被第一行创建并初始化了。另一方面,如果我将Initialize()中的第一行放在DoStuff中,则无法再访问它。它超出了范围,(更不用说在C++中使用'new'或不使用它们之间的区别)。你怎样才能创建一个类变量的持有者,以便我可以在一个地方初始化它,并在另一个地方访问它?或者我从根本上弄错了什么?

在此先感谢!访问RinaDingDong()

Phone *myPhone; 

void Initialise() 
{ 
    myPhone = new Phone(); 
} 

void DoStuff() 
{ 
    myPhone->RingaDingDong(); 
} 

仅有的两个变化是在myPhone声明添加*->,而不是.

+3

我试过写一个答案,但问题涉及太多的东西。相反,标准的SO C++响应#1:[阅读一本好的介绍书](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 –

+0

同意CPP。了解一种语言的特定机制是一回事,但从理解语言的习语来看,这是一个很长的过程。不幸的是,你的例子太短暂了,无法提供有意义的建议,所以我会留下一个有条件的“不要使用新的”或“指针”。 –

回答

2

如果你的电话构造函数没有参数,那么你的生活很简单 - 你不需要在Initialize方法中新增电话。它将在创建对象时为您创建,并且您的生命周期将得到管理。

如果您需要获取参数,并且没有Initialize()方法或某些set方法,那么您可能需要使用一个指针(有时可以为null)并且具有Initialize()调用新的并通过这些参数。在使用它之前,你的其他代码需要检查指针是否为空。此外,您需要管理生命周期(通过编写big 3)或使用智能指针(如C++ 11中的shared_ptr)。这不应该是你的第一选择。

2

您可以使用指针new运算符。您还需要释放它,因为new被分配内存:

void destroy() 
{ 
    delete myPhone; 
} 

请注意,如果你这样做myPhone将是一个指向Phone不是实际Phone

+0

可能更多的是OP的目的。 – Ramy

+4

除非您真的需要它,否则不应使用原始指针或免费商店。 –

+0

真棒,好吧。仍然适应使用指针,现在我正在理解为什么如此多的全局变量是指针。一个问题 - 我是否认为Phone myPhone;有一种内置的'新'内置,但编译器保持跟踪,所以你不需要调用'删除'? – SirYakalot

0

我认为你需要刷一下指针。 你正在尝试做的事情可能是用指针。

我的问题是,初始化内部的行在C++中是不必要的,因为在此之前,一个新的实例已经被第一行创建和初始化。

这是不正确的。您提供的评论仅适用于构造函数。从您的puesdo代码中,函数initialize是一个全局函数,不是类的成员函数。

另一方面,如果我把第一行放在Initialise()中,我不能再在DoStuff中访问它。它超出了范围,(更不用说在C++中使用'new'或不使用它们之间的区别)。

请参考任何关于指针的书,你可以有一个全局指针并用new进行初始化。这可以用于doStuff

+2

我相信当他说“已经创建了一个新实例”时,他指的是这样的:'Phone myPhone;' – quasiverse

0

如果你来自C#,你知道你有两种类型的对象:class和struct。

该类被复制,分配并传递给函数引用。所以,他们正在使用参考语义。该类也分配在堆中(使用新的)。

该结构正在实现值复制语义。结构分配在堆栈上(int,double和其他内置类型都是struct)。你不能把结构多态性。

在C++中,你没有这个区别。类和结构本质上是相同的(默认访问级别的一部分)。确定复制语义并非是类的声明,而是实例对类的声明。

如果你创建一个指针,行为与c#中的类非常相似。如果你创建一个对象,语义就会和c#中的一个结构类似。

C++也有引用,你应该阅读关于指针和引用的区别。

0

凯特格雷戈里的答案是正确的,但我想详细阐述一点。 C++中更强大的想法之一是堆栈分配的对象由其包含的范围所拥有。例如,如果你想要写一个包含电话一类,你只是写:每一个司创建时间

class Secretary { 
    Phone myPhone; 
}; 

而现在,一个电话对象将自动使用其默认的构造函数初始化。更重要的是,每当秘书对象被销毁时,它所包含的Phone对象也被销毁。如果要使用不同的构造函数的电话,您可以在局长的构造函数中使用初始化列表:

class Secretary { 
private: // members 
    Phone myPhone; 
    Phone myCellPhone; 

public: // methods 
    Secretary() : myPhone("phone constructor", 12, " args") {} 
}; 

在这种情况下的MyPhone正在利用其3个参数的构造函数初始化,myCellPhone使用它的默认构造函数初始化通常。