纯 C++ 模拟 Qt QObject 对象树

纯 C++ 模拟 Qt QObject 对象树,仅一层继承

要点:

  1. 基类MyQObject:实现对象树全部逻辑(父指针、子列表、setParent、虚析构递归释放子节点)
  2. 一层派生类MyWidget : public MyQObject,模拟 QWidget
  3. 基类析构virtual,保证多态调用子类析构
  4. 禁用拷贝构造、赋值,和 QtQ_DISABLE_COPY对齐
  5. 不引入 MOC、信号槽,只复刻对象树内存回收

cpp

#include <iostream>
#include <list>
#include <string>

// 模拟 Qt QObject 基类
class MyQObject
{
private:
    MyQObject* m_parent = nullptr;
    std::list<MyQObject*> m_children;
    std::string m_name;

    void addChild(MyQObject* child)
    {
        m_children.push_back(child);
    }

    void removeChild(MyQObject* child)
    {
        m_children.remove(child);
    }

public:
    explicit MyQObject(std::string name)
        : m_name(std::move(name))
    {
        std::cout << "[MyQObject 构造] " << m_name << "\n";
    }

    MyQObject(std::string name, MyQObject* parent)
        : m_name(std::move(name))
    {
        std::cout << "[MyQObject 构造] " << m_name << "\n";
        setParent(parent);
    }

    void setParent(MyQObject* newParent)
    {
        // 脱离旧父
        if (m_parent != nullptr)
        {
            m_parent->removeChild(this);
        }
        m_parent = newParent;
        // 挂载新父
        if (newParent != nullptr)
        {
            newParent->addChild(this);
        }
    }

    MyQObject* parent() const
    {
        return m_parent;
    }

    // 虚析构:继承必须virtual,实现多态析构
    virtual ~MyQObject()
    {
        std::cout << "[MyQObject 析构 begin] " << m_name << "\n";

        // 递归释放所有子对象
        for (auto it = m_children.begin(); it != m_children.end();)
        {
            MyQObject* child = *it;
            it = m_children.erase(it);
            delete child;
        }

        // 自己从父的子列表移除,防止野指针
        if (m_parent != nullptr)
        {
            m_parent->removeChild(this);
        }
        std::cout << "[MyQObject 析构 end] " << m_name << "\n";
    }

    // 禁用拷贝,等价Q_DISABLE_COPY
    MyQObject(const MyQObject&) = delete;
    MyQObject& operator=(const MyQObject&) = delete;
};

// =========一层继承:模拟 QWidget,继承 MyQObject=========
class MyWidget : public MyQObject
{
public:
    MyWidget(std::string name, MyQObject* parent = nullptr)
        : MyQObject(std::move(name), parent)
    {
        std::cout << "    -->[MyWidget 构造]\n";
    }

    ~MyWidget() override
    {
        std::cout << "    -->[MyWidget 析构]\n";
    }
};


int main()
{
    std::cout << "==== 创建对象树:父为MyWidget,子为MyWidget ====\n";
    MyQObject* window = new MyWidget("MainWindow");
    MyQObject* btn = new MyWidget("Button", window);

    std::cout << "\n==== delete父对象,自动回收全部子对象 ====\n";
    delete window;

    return 0;
}

运行输出

plaintext

==== 创建对象树:父为MyWidget,子为MyWidget ====
[MyQObject 构造] MainWindow
    -->[MyWidget 构造]
[MyQObject 构造] Button
    -->[MyWidget 构造]

==== delete父对象,自动回收全部子对象 ====
[MyQObject 析构 begin] MainWindow
[MyQObject 析构 begin] Button
    -->[MyWidget 析构]
[MyQObject 析构 end] Button
    -->[MyWidget 析构]
[MyQObject 析构 end] MainWindow

关键逻辑说明

  1. 继承关系MyWidget public MyQObject,仅一层继承;子类不用写任何父子管理代码,全部复用基类。
  2. 虚析构virtual ~MyQObject()MyQObject*基类指针指向派生类MyWidget,delete 时多态,先执行子类~MyWidget(),再执行基类~MyQObject()。 没有 virtual,只会
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值