6

I need reliable information about "this" subject:

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

Of course, calling virtual functions in contructor OR initialization list is a bad idea. The Question is: can this code

mpAnotherWidget( new QWidget( this ) )

lead to undefined behavior?! And if so: why ?

Please quote your sources if you can! Thanks!

Félix Cantournet
  • 1,941
  • 13
  • 17
LalaBox
  • 243
  • 2
  • 4
  • 10

3 Answers3

4

It depends on what QWidget does with the pointer it is given. It is perfectly fine to pass around a reference or pointer to a half-constructed object as long as the called code does not access the underlying object. You need to look into the documentation of QWidget to know whether it touches the object or just stores the pointer.


In the particular case of Qt, reading the documentation, it is calling the constructor of QWidget, the argument is of type QWidget*, and this is only used to cast to the base pointer. Obtaining the pointer to the base is guaranteed in 12.7/3 as the requirement for the conversion is that the construction of X and the construction of all of its direct or indirect bases that directly or indirectly derive from B shall have started. The pointer is then passed to the QWidget constructor that may use it in any way it wants, since the constructor for the base QWidget has already completed before the constructor for the mpAnotherWidget starts.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • As far as I know, it depens on what members of the objects are accessed. If the member is already initialized, when the function is called, there should be no problem – MikeMB Apr 01 '15 at 11:52
  • The standard does not go into those details, and yes, if it only accesses members already initialized it will probably do the right thing, but it is still not sanctioned by the standard. – David Rodríguez - dribeas Apr 01 '15 at 11:53
  • the given is yet C++ standard behavior knowledge. I need Qt specific knowledge: What's the Qt-framework doing with that this-pointer? Why could it possibly lead to undefiened behavoir? – LalaBox Apr 01 '15 at 12:06
2

In general this is an uncommon technique, and risky because it's unclear what expectations the other code may have.

But as you correctly point out, this is Qt code. Here passing pointers to constructors is quite common and expected. Your windows consist of a lot of objects knowing about each other.

In particular, QWidgets can have other QWidgets as parents, and this is supported by passing the parent pointer to the child. And since the parent often is the class constructing the children, the parent pointer is then just this. So your code is perfectly normal Qt style.

Now, is this safe? As written, yes. The constructor for the child widget, QWidget::QWidget assumes that the parent pointer does point to an already constructed QWidget, and it does in your example. But it doesn't assume much more. How could it? QWidget doesn't know anything about your class. In particular, it can't even call pure virtual methods since QWidget does't have those.

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

It is OK if the pointer is not going to be used immediately, but stored for future use.

But in the case of QObject derived, the pointer is passed to establish parent-child object ownership, meaning the pointer will be used before the object it points to is fully constructed. Thus it is undefined behavior - anything could happen and if it does, it will be bad.

dtech
  • 47,916
  • 17
  • 112
  • 190