6

我需要关于“这个”主题的可靠信息:

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

当然,在构造函数 OR 初始化列表中调用虚函数是个坏主意。问题是:这个代码可以吗

mpAnotherWidget( new QWidget( this ) )

导致未定义的行为?!如果是这样:为什么?

如果可以的话,请引用您的来源!谢谢!

4

3 回答 3

4

这取决于QWidget给定的指针做什么。只要被调用的代码不访问底层对象,就可以将引用或指针传递给半构造对象。您需要查看文档QWidget以了解它是触摸对象还是仅存储指针。


在 Qt 的特定情况下,阅读文档,它正在调用 的构造函数QWidget,参数类型为QWidget*,并且this仅用于转换为基指针。在 12.7/3 中保证了获得指向基址的指针,因为转换的要求是X 的构造及其直接或间接从 B 派生的所有直接或间接基址的构造应该已经开始。然后将指针传递给QWidget可以以任何方式使用它的构造函数,因为基QWidget类的构造函数在开始的构造函数之前已经完成mpAnotherWidget

于 2015-04-01T11:49:47.637 回答
2

一般来说,这是一种不常见的技术,并且有风险,因为不清楚其他代码可能有什么期望。

但正如您正确指出的那样,这是 Qt 代码。这里将指针传递给构造函数是很常见的,也是意料之中的。您的窗口由许多相互了解的对象组成。

特别是,QWidgets 可以有其他 QWidgets 作为父级,这通过将父级指针传递给子级来支持。而且由于父级通常是构造子级的类,因此父级指针就是this. 所以你的代码是完全正常的 Qt 风格。

现在,这安全吗?正如所写,是的。子小部件的构造函数QWidget::QWidget假定父指针确实指向已构造的QWidget,并且在您的示例中也是如此。但它并没有假设更多。怎么可能?QWidget 对您的课程一无所知。特别是,它甚至不能调用纯虚方法,因为QWidget没有那些。

于 2015-04-01T13:54:38.990 回答
1

如果指针不立即使用,但存储以备将来使用,则可以。

但是在QObject派生的情况下,传递指针以建立父子对象所有权,这意味着指针将在其指向的对象完全构造之前使用。因此,这是未定义的行为 - 任何事情都可能发生,如果发生,那将是糟糕的。

于 2015-04-01T14:07:38.213 回答