QObject
происхождения и продолжительность хранения являются ортогональными вопросами и должно быть рассмотрено отдельно.
Вы не можете переместить QObject
, удерживая другое QObject
s в другой поток, если все принадлежащие ему объекты не имеют владельца, установленного в качестве родителя. Таким образом, не устанавливая родителя, вы преждевременно ограничиваете функциональность родительского класса.
В современном 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!!