2015-04-01 8 views
3

мне нужна надежной информация о «этой» теме:Использует «это» в списке инициализации contructor, особо опасном с Qt?

class MyClass, public QWidget 
{ 
public: 
    MyClass(QWidget * parent = NULL) 
     :QWidget(parent), 
     mpAnotherWidget(new QWidget(this)){}; 
private: 
    QWidget * mpAnotherWidget; 
}; 

Конечно, вызов виртуальных функций в застройщик ИЛИ списке инициализации это плохая идея. Вопрос: может ли этот код

mpAnotherWidget(new QWidget(this)) 

привести к неопределенному поведению ?! И если да: почему?

Просьба указать ваши источники, если вы можете! Благодаря!

+3

http://isocpp.org/wiki/faq/ctors#using-this-in-ctors – vahancho

ответ

2

Это зависит от того, что QWidget делает с указанием указателя. Прекрасно передавать ссылку или указатель на полуконструированный объект, если вызываемый код не обращается к базовому объекту. Вам нужно изучить документацию QWidget, чтобы узнать, касается ли она касания объекта или просто сохраняет указатель.


В частном случае Qt, чтение документации, он звонит конструктор QWidget, аргумент типа QWidget* и this используется только приведение к базовому указателю. Получение указателя на базу гарантируется в 12.7/3, так как требование конверсии заключается в том, что будет построено строительство X и построено все его прямые или косвенные основания, которые прямо или косвенно выводятся из B,. Затем указатель передается в конструктор QWidget, который может использовать его любым способом, так как конструктор базы QWidget уже завершен до того, как начинается конструктор для mpAnotherWidget.

+0

Насколько я знаю, это зависит от того, к каким элементам доступа обращаются.Если элемент уже инициализирован, когда функция вызывается, не должно быть никаких проблем. – MikeMB

+0

Стандарт не входит в эти детали, и да, если он только обращается к уже инициализированным членам, он, вероятно, пойдет правильно, но все равно не санкционированный стандартом. –

+0

данное еще знание о стандартном поведении C++. Мне нужны специфические знания Qt: что делает Qt-framework с этим указателем? Почему это может привести к неуверенному поведению? – LalaBox

1

В общем, это необычная техника и рискованность, поскольку неясно, какие ожидания может иметь другой код.

Но, как вы правильно указываете, это код Qt. Здесь прохождение указателей на конструкторы довольно распространено и ожидается. Ваши окна состоят из множества объектов, знающих друг о друге.

В частности, QWidgets может иметь другие QWidgets в качестве родителей, и это поддерживается передачей родительского указателя на дочерний элемент. И поскольку родительский элемент часто является классом, строящим дочерние элементы, родительский указатель тогда равен this. Таким образом, ваш код абсолютно нормальный стиль Qt.

Теперь, это сейф? Как написано, да. Конструктор дочернего виджета QWidget::QWidget предполагает, что родительский указатель указывает на уже построенный QWidget, и это в вашем примере. Но это не предполагает гораздо больше. Как это могло быть? QWidget ничего не знает о вашем классе. В частности, он даже не может назвать чистые виртуальные методы, так как QWidget не имеет этих.

0

Это нормально, если указатель не будет использоваться немедленно, но сохранен для использования в будущем.

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