3

考虑以下代码:

#include <QObject>

class A : public QObject
{
    Q_OBJECT
    public: 
        A(QObject* parent = 0) : QObject(parent) {}
}

int main()
{
    A a = new A();
    return 0;
}

为什么我可以将类型对象分配给类型A*变量A而编译器(或运行时)不会抱怨?

4

1 回答 1

4

在这段代码中, 的构造函数A用于an转换A*为 type 的对象A,而不是分配它。一般来说,编译器允许隐式使用匹配的构造函数作为转换运算符,因此以下是合法代码:

struct B
{
    B(int i){}
}
int main()
{
    B b = 5;
    return 0;
}

在问题的代码中,A*new运算符产生的未命名用作parent的构造函数的参数A。这是允许的,因为A它派生自QObject(因此与参数列表匹配)。但是,这显然是不受欢迎的行为,因为a不是由 返回的对象new,而是该对象的A父类型对象。(此外,new'ed 对象永远不会是deleted,导致内存泄漏。)

为了防止这种微妙的错误,一般建议制作-QObject派生类的构造函数,explicit以防止编译器误将其用作转换运算符。(这也适用于类似的情况,不仅适用于 Qt。)使用以下修改后的代码,编译器将捕获错误:

class A : public QObject
{
    Q_OBJECT
    public: 
        explicit A(QObject* parent = 0) : QObject(parent) {}
}
于 2015-05-19T09:59:21.303 回答