纯 C++ 模拟 Qt QObject 对象树,仅一层继承
要点:
- 基类
MyQObject:实现对象树全部逻辑(父指针、子列表、setParent、虚析构递归释放子节点) - 一层派生类
MyWidget : public MyQObject,模拟 QWidget - 基类析构virtual,保证多态调用子类析构
- 禁用拷贝构造、赋值,和 Qt
Q_DISABLE_COPY对齐 - 不引入 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
关键逻辑说明
- 继承关系:
MyWidget public MyQObject,仅一层继承;子类不用写任何父子管理代码,全部复用基类。 - 虚析构
virtual ~MyQObject():MyQObject*基类指针指向派生类MyWidget,delete 时多态,先执行子类~MyWidget(),再执行基类~MyQObject()。 没有 virtual,只会

1072

被折叠的 条评论
为什么被折叠?



