1

我来自一个Java背景,我最近开始Qt学习C++. 在进行一些编码时,我对对象创建和成员声明产生了一些疑问:

假设我有一个声明如下的类:

类A.h:

class ClassA {

private:
    MyObject myObj;
    QString *declaredArray;
    QSharedPointer<MyObject> obj;
public:
    void setInfo();
}

A类.cpp

void ClassA::setInfo() {
    declaredArray = new QString[5];
    obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
}

声明的标头中发生了什么MyObject myObj;?是否使用不带参数的构造函数MyObject在堆栈中创建类型的对象并将其分配给变量?myObj或者只声明了一个准备存储MyObject对象的空变量?

我如何将在ClassA.cpp堆栈中创建的新对象分配给myObj变量?

declareArray是在堆中创建的 s 数组int,我应该添加带有 a 的析构函数delete declaredArray;以避免内存泄漏吗?

声明的标头中发生了什么QSharedPointer<MyObject> obj;?是否MyObject创建了一个空指针?ClassA.cpp( )中的赋值obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);是否正确?

4

1 回答 1

3

无论在哪里分配(如果在堆栈上分配,空间 for将在堆栈上) ,都会有空间 for myObj(大小为)。MyObjectClassAClassAmyObj

如果存在适用的默认构造函数MyObject,并且:

  1. 您定义一个显式的默认构造函数,如下所示:
    类():
        我的对象(),
        声明数组(NULL),
        对象(NULL){}
  1. 您没有声明构造函数,因此会导致编译器添加隐式声明的默认构造函数,这与上述功能大致相似。

... 然后myObj将被初始化为默认值 ( MyObject())。

另请注意,您创建的任何堆分配内存new都应delete在销毁时释放。因此,您还应该有一个析构函数:

~ClassA() {
    if (delcaredArray != NULL) {
        delete[] declaredArray;
    }
}

myObj多亏了 RAII ,如果在构造obj函数中显式初始化,您将不需要破坏。ClassA但是,如果它们不是,那么您将需要显式地破坏它们(例如,在共享指针的情况下,递减计数器)。


要明确回答您的其他问题:

MyObject myObj; 的标题中发生了什么 被宣布?MyObject 类型的对象是否在堆栈中创建并使用不带参数的构造函数分配给变量 myObj?或者只声明了一个准备存储 MyObject 对象的空变量?

myObj如果默认构造函数存在并且已被创建(隐式或显式),则只会被默认构造(使用不带参数的构造函数构造)。

在 ClassA.cpp 中,如何将堆栈中创建的新对象分配给 myObj 变量?

如果myObj是有效的,那么myObj = MyObject(...);(没有new关键字)就足够了。请注意,这将调用operator=()(赋值运算符) on myObj,因此myObj需要已经定义它才能完全定义行为。如果它已经是默认构造的,那么myObj = MyObject(...);很好。

declareArray 是在堆中创建的 int 数组,我应该添加一个带有 delete 声明数组的析构函数吗?避免内存泄漏?

是的,你应该,如上所示。

QSharedPointer obj; 的标头中发生了什么 被宣布?是否创建了指向 MyObject 的空指针?ClassA.cpp (obj = QSharedPointer(new MyObject, doDeleteLater);) 中的分配是否正确?

QSharedPointer的文档显示其默认构造函数是QSharedPointer指向NULL. 如果您有一个默认构造函数可以适当地为成员调用默认构造函数,那么您应该没问题。

QSharedPointer如您所示,可以使用赋值运算符将正确构造的(例如默认或非默认构造,但已初始化)分配给(obj = QShardPointer<MyObject>(new MyObject))

于 2015-01-08T05:43:00.703 回答