我来自Java
背景,最近我开始使用Qt
了解C++
。在进行一些编码时,对于对象创建和成员声明的一些疑问已经出现在我身上:
假设我有一个声明如下的类:
ClassA.h:
class ClassA {
private:
MyObject myObj;
QString *declaredArray;
QSharedPointer<MyObject> obj;
public:
void setInfo();
}
ClassA.cpp
void ClassA::setInfo() {
declaredArray = new QString[5];
obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
}
宣布MyObject myObj;
的标题中发生了什么?是否在堆栈中创建了MyObject
类型的对象,并使用不带参数的构造函数将其分配给变量myObj
?或者只声明了一个准备存储MyObject
对象的空变量?
在ClassA.cpp
中,如何将堆栈中创建的新对象分配给myObj
变量?
declaredArray 是在堆中创建的int
数组,我应该添加一个带有delete declaredArray;
的析构函数来避免内存泄漏吗?
宣布QSharedPointer<MyObject> obj;
的标题中发生了什么?是否创建了一个指向MyObject
的空指针? ClassA.cpp
(obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
)中的作业是否正确?
答案 0 :(得分:3)
myObj
(大小为MyObject
)的空间,只要ClassA
被分配(如果ClassA
分配在堆栈上,{{1}的空间将在堆栈上。)
如果myObj
存在适用的默认构造函数,则可以:
ClassA() : myObj(), declaredArray(NULL), obj(NULL) { }
...然后MyObject
将初始化为默认值(myObj
)。
另请注意,使用MyObject()
创建的任何堆分配内存都应在销毁时使用new
取消分配。因此,您还应该有一个析构函数:
delete
感谢RAII,如果在~ClassA() {
if (delcaredArray != NULL) {
delete[] declaredArray;
}
}
构造函数中显式初始化,则无需销毁myObj
和obj
。但是,如果它们不是,那么你将需要明确地破坏它们(例如,在共享指针的情况下,减少计数器)。
明确回答您的其他问题:
如果默认构造函数存在且已经创建(隐式或显式),则在MyObject myObj的标题中发生了什么;被宣布?是否在堆栈中创建了MyObject类型的对象,并使用不带参数的构造函数将其分配给变量myObj?或者只声明了一个准备存储MyObject对象的空变量?
ClassA
将仅默认构造(使用不带参数的构造函数构造)。
在ClassA.cpp中,如何将堆栈中创建的新对象分配给myObj变量?
如果myObj
有效,那么myObj
(没有myObj = MyObject(...);
关键字)就足够了。请注意,这将在new
上调用operator=()
(赋值运算符),因此需要已为此定义myObj
以完全定义行为。如果它已经默认构造,那么myObj
就可以了。
declaredArray是在堆中创建的int数组,我应该添加一个带有delete declaredArray的析构函数;避免内存泄漏?
是的,你应该,如上所示。
在QSharedPointer obj的标题中发生了什么;被宣布?是否创建了一个指向MyObject的空指针? ClassA.cpp中的赋值(obj = QSharedPointer(new MyObject,doDeleteLater);)是否正确?
documentation for QSharedPointer显示其默认构造函数是指向myObj = MyObject(...);
的{{1}}。如果你有一个默认的构造函数,它正确地调用了成员的默认构造函数,那么你应该没问题。
可以使用正如您所示的赋值运算符指定正确构造的(例如,默认或非默认构造但已初始化)QSharedPointer
:NULL
。