考虑以下代码:
#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
而编译器(或运行时)不会抱怨?
考虑以下代码:
#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
而编译器(或运行时)不会抱怨?
在这段代码中, 的构造函数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 对象永远不会是delete
d,导致内存泄漏。)
为了防止这种微妙的错误,一般建议制作-QObject
派生类的构造函数,explicit
以防止编译器误将其用作转换运算符。(这也适用于类似的情况,不仅适用于 Qt。)使用以下修改后的代码,编译器将捕获错误:
class A : public QObject
{
Q_OBJECT
public:
explicit A(QObject* parent = 0) : QObject(parent) {}
}