Отношения родитель-потомок установлены для переменных-членов в Qt

Я читал документацию Qt здесь. Я нашел следующее предложение под заголовком «Thread Affinity».

Примечание. Переменные-члены QObject не становятся автоматически его дочерними элементами. Отношение родитель-потомок должно быть установлено либо путем передачи указателя на конструктор дочернего элемента, либо путем вызова setParent().

Я не понимаю, что он упомянул как установление родительско-дочерних отношений между объектом и его переменными-членами. Я знаю только отношения родитель-потомок между суперклассом и подклассом.

Кто-нибудь может объяснить мне эту фразу? Если вы можете привести пример, это будет более полезно.

Спасибо за прочтение.


person Hareen Laks    schedule 17.09.2015    source источник


Ответы (3)


Переменные-члены НЕ станут дочерними объектами без явной установки свойства parent. Подкласс Object обычно берет другой QObject в качестве родителя в конструкторе.

class Test : public QObject
{
  Q_OBJECT
  public:
    Test(QObject* prnt) 
      : QObject(prnt),
        timerNoPrnt(), // Test object is NOT the parent. This won't be deleted when Test object gets deleted.
        timer(this)    // Test object is the parent here. This will be deleted when Test object gets deleted. 
    {
      timerNoPrnt->setParent(this); // now parent assigned.
    }
  private:
    QTimer*           timerNoPrnt;   // member variable
    QTimer*           timer;
}
person ramtheconqueror    schedule 17.09.2015
comment
Спасибо всем вам. Я добавляю последнее предложение этой заметки. Без этого шага переменные-члены объекта останутся в старом потоке при вызове moveToThread(). Это означает, что если объект перемещается в другой поток, он не может получить доступ к своим переменным-членам. Я имею в виду потеряли свои ценности. правильно? - person Hareen Laks; 18.09.2015
comment
@HareenLaks Если это произойдет, вы можете получить доступ к переменным-членам, но это больше не является потокобезопасным. - person Kuba hasn't forgotten Monica; 18.09.2015

QObject (A) может иметь другие QObject (B) в качестве переменных-членов. B не создаются автоматически с A их родителем, и это не обязательно. Это возможно, но не обязательно и не делается автоматически.

Существует не только отношение родитель-потомок между классом и его суперклассом (базовым классом), но также между QWidget и встроенными виджетами. Он используется, например. чтобы уничтожить виджеты в правильном порядке в конце.

См. документ здесь и ответ на SO относительно управления памятью здесь.

person Gombat    schedule 17.09.2015

QObject — это контейнер объектов. Содержащиеся в нем объекты называются его дочерними элементами, а содержащий их объект считается родительским для этих дочерних элементов. Само по себе это ничего не говорит о том, как и где распределяются дети. Давайте посмотрим на некоторые сценарии в С++ 11:

void test() {
  QObject aParent;
  // children of automatic storage duration
  QObject aChild1{&aParent}, aChild2;
  aChild2->setParent(&aParent);
  // children of dynamic storage duration
  auto aChild3 = new QObject{&aParent};
  auto aChild4 = new QObject;
  aChild4->setParent(&aParent);
}

struct Parent : QObject {
  QObject aChild5 { this };
  QObject * aChild6 { new QObject };
  QObject notAChild;
  Parent() { aChild6->setParent(this); }
};

Функция test() демонстрирует, как объект может быть родительским для некоторых дочерних объектов с автоматической и динамической продолжительностью хранения. Родительский объект может быть задан в конструкторе или в качестве аргумента метода setParent.

Класс Parent демонстрирует, что объекты-члены могут быть дочерними элементами родительского класса, но не обязательно. Значения членов имеют продолжительность автоматического хранения, но не все дочерние объекты. Объект, на который указывает aChild6, имеет продолжительность динамического хранения. Поскольку QObject удаляет все дочерние элементы в своем деструкторе, эффективная продолжительность хранения объекта в aChild6 определяется автоматически: вам не нужно беспокоиться об удалении объекта.

person Kuba hasn't forgotten Monica    schedule 17.09.2015