gpt4 book ai didi

c++ - 什么是更好的?如果 child 是类(class)成员,是否为 child 设置 QObject parent ?

转载 作者:搜寻专家 更新时间:2023-10-31 01:38:08 26 4
gpt4 key购买 nike

class A : public QObject {
A() : b(this) {} // !


class B : public QObject {
B(QObject* parent)
};
B b;
}

如果子对象不是动态的,我应该设置父对象吗?这两种情况有什么区别?

什么更好,有什么区别?

class A : public QObject {
A() : b(new B(this)) {} // !


class B : public QObject {
B(QObject* parent)
};
B* b;
}

class A : public QObject {
A() : b(new B()) {} // !


class B : public QObject {
B()
};
smart_ptr<B> b;
}

最佳答案

QObject 出身和存储持续时间是正交问题,应单独解决。

您不能将持有其他 QObjectQObject 移动到另一个线程,除非所有拥有的对象都将所有者设置为父对象。因此,通过不设置父类,您会过早地限制父类的功能。

在现代 C++ 中,具有动态存储持续时间的子 QObject 应该通过资源管理器保存。这样的管理器可以是智能指针,或者只是拥有对象。回想一下,QObject 隐含地也是一个QObject 容器。因此,甚至不需要有一个指向子对象的显式成员指针 - 假设您只需要在所有者构造期间直接引用该对象。

一般来说,通过让任何成员具有动态存储持续时间,您会过早地悲观,除非它们的构造函数非常昂贵并且您希望将构造延迟到以后。

因此,如果您没有使用 PIMPL idiom ,那么所有成员都应该在对象本身中具有自动存储持续时间:

// A.h
class A : public QObject {
Q_OBJECT
QSerialPort m_port { this };
QThread m_thread { this };
....
};

否则,它们属于 PIMPL:

// A.h
class APrivate;
class A : public QObject { ... };

// A.cpp
#include "A.h"
class APrivate {
public:
A * const q_ptr;
QSerialPort m_port { q_ptr };
QThread m_thread { q_ptr };
APrivate(A * q) : q_ptr(q) {}
};

还应该指出的是,为了“加速”编译或“减少依赖性”而使用指向前向声明的不完整类型的指针是一种反模式。如果您愿意在头文件中公开实现细节,只需按值保留所有成员 - 如上面的第一个示例所示。如果您担心过度依赖并想隐藏您的实现,请使用 PIMPL。指向前向声明类的指针的“中间道路”迫使您进行额外的动态存储分配,因此是一种不灵活的怪物,对任何人都没有帮助。

// DO NOT WRITE CODE LIKE THIS!!
class QSerialPort;
class QThread;
class A : public QObject {
Q_OBJECT
QSerialPort * m_port;
QThread * m_thread;
...
};
// DO NOT WRITE CODE LIKE THIS!!

关于c++ - 什么是更好的?如果 child 是类(class)成员,是否为 child 设置 QObject parent ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33238236/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com