为啥我可以将 QObject* 分配给 QObject?

Posted

技术标签:

【中文标题】为啥我可以将 QObject* 分配给 QObject?【英文标题】:Why can I assign a QObject* to a QObject?为什么我可以将 QObject* 分配给 QObject? 【发布时间】:2015-07-31 02:12:45 【问题描述】:

考虑以下代码:

#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 类型的变量而编译器(或运行时)不会抱怨?

【问题讨论】:

我希望这个问答类型的问题在这里是合适的。我们最近偶然发现了这种行为,不得不考虑一下解决方案,所以我希望它对这里的某人有用:-) 抱歉,如果不是,否则将删除它。 是的,自我回答的问题完全没问题(甚至鼓励),只要它们符合所有正常的质量期望。据我所知,你的确实如此。 blog.***.com/2011/07/… 感谢您的链接 :-) 【参考方案1】:

在此代码中,A 的构造函数用于将A*转换A 类型的对象,而不是分配它。一般来说,编译器允许隐式使用匹配的构造函数作为转换操作符,所以下面的代码是合法的:

struct B

    B(int i)

int main()

    B b = 5;
    return 0;

在问题的代码中,由new 运算符产生的未命名A* 用作A 的构造函数的parent 参数。这是允许的,因为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) 

【讨论】:

以上是关于为啥我可以将 QObject* 分配给 QObject?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以将字符分配给字符串对象而不是字符串对象的向量?

Qt智能指针

为啥可以将整数值分配给未初始化的指针

为啥 SQL Server 不允许我启用混合身份验证模式,以便我可以使用 sa 用户将角色分配给其他用户?

为啥我不能将 UIView 分配给 self.view?

为啥可以通过构造函数将临时值分配给引用?