C++对象析构顺序问题——由QObject::desroyed展开的思考
C++对象析构顺序问题——由QObject::desroyed展开的思考
C++析构函数执行的顺序是最先执行继承链最末端的子类的,最后执行顶层的基类的。
而 QObject::destroyed(QObject* obj = nullptr)
信号在 Qt 文档中说是“在 obj
被完全析构时之前立即触发,并且不会被阻塞”。这里的“完全析构”指的是按照析构函数调用的顺序,存在析构了子类部分但还没析构基类部分的时刻。
因此,下例中会出现先打印析构函数中的输出,然后才调用槽函数的情况。不过,在对象还未被完全析构时,在析构函数中使用其成员(不管是子类部分还是基类部分)都是安全的,因为析构函数的执行是在OS释放这块内存之前。
#include <QCoreApplication> #include <QDebug> class MyObjectBase : public QObject { Q_OBJECT public: MyObjectBase() { qWarning() << "MyObjectBase 构造"; } virtual ~MyObjectBase() { qWarning() << "MyObjectBase 析构"; } void ownBaseMethod() { qWarning() << "父类的非虚方法" << m_father; } virtual void sharedMethod() { qWarning() << "父类的虚方法" << m_father; } int m_father = 100; }; class MyObjectDerived final: public MyObjectBase { Q_OBJECT public: MyObjectDerived() { qWarning() << "MyObjectDerived 构造"; } virtual ~MyObjectDerived() { qWarning() << "MyObjectDerived 析构"; } void ownDerivedMethod() { qWarning() << "子类的独有方法" << m_father; } void sharedMethod() override { qWarning() << "子类重写的虚方法" << m_father << m_child; } int m_child = 200; }; class Tracker : public QObject { Q_OBJECT public: Tracker(MyObjectDerived* target) : target(target) {} public slots: void onDestructor() { qWarning() << "About to be destroyed!"; target->ownBaseMethod(); target->ownDerivedMethod(); target->sharedMethod(); } private: MyObjectDerived* target; }; int main(int argc, char** argv) { QCoreApplication app(argc, argv); MyObjectDerived *obj = new MyObjectDerived(); Tracker tracker(obj); QObject::connect(obj, &QObject::destroyed, &tracker, &Tracker::onDestructor); delete obj; return app.exec(); } // moc main.cpp -o main.moc #include "main.moc"
输出:
MyObjectBase 构造 MyObjectDerived 构造 MyObjectDerived 析构 MyObjectBase 析构 About to be destroyed! 父类的非虚方法 100 子类的独有方法 100 子类重写的虚方法 100 200
本文作者:3的4次方
本文链接:https://www.cnblogs.com/3to4/p/18336193
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步