qt - 在父窗口/窗口小部件类中初始化子窗口小部件的目的是什么?

时间:2014-02-23 05:38:31

标签: c++ qt initialization qwidget qtgui

在Qt中的VideoWidget和Secure Socket Client示例中,在那里显示的代码将父窗口小部件中的子窗口小部件初始化,如下所示:

SslClient::SslClient(QWidget *parent)
: QWidget(parent), socket(0), padLock(0), executingDialog(false)

VideoPlayer::VideoPlayer(QWidget *parent)
: QWidget(parent)
, mediaPlayer(0, QMediaPlayer::VideoSurface)
, playButton(0)
, positionSlider(0)
, errorLabel(0)

然而,在代码中,我看到以下内容:

playButton = new QPushButton;

或在安全套接字客户端的情况下,这:

padLock = new QToolButton;

为什么在构造函数中将在代码中初始化时进行初始化?

3 个答案:

答案 0 :(得分:3)

  

为什么在构造函数中将在代码中初始化时进行初始化?

这样实现是异常安全的。假设你有这个代码:

SslClient::SslClient(QWidget *parent)
: QWidget(parent), socket(0), padLock((QToolButton*)(0x0BEEF)), executingDialog(false) {
  throw std::exception();
  padLock = new QToolButton;
}

析构函数将删除padLock,但它有垃圾值,并且您有未定义的行为。回想一下,删除nullptr是安全的(就像在C中调用free(NULL)一样)。垃圾挂锁值显示未初始化时发生的情况。投掷表明可能会抛出一些干预代码。具体而言,如果分配不成功,任何干预new都会抛出。 new在失败时不会返回(如:它抛出std::bad_alloc而不是返回,因此返回值的概念根本不适用。)

如果正在编写惯用的C ++,那么指针不应该是一个裸指针,而应该是std::unique_ptrQScopedPointer,然后这个问题就会消失。您不必记住将指针初始化为零,并且您不必记得清理它。 RAII为您赢得了很多胜利。这就是你真正使用C ++时所使用的秘密武器。

C ++ RAII习惯用法本身并不存在于任何其他常见的编程语言中。在允许它的语言中(例如Java,C#,F#,Python,OCaml和Common Lisp),惯用的解决方法是定义更高阶的with_resource函数,请参阅OCaml的示例,JavaPython以及Python again。基本上,在C ++以外的语言中,特别是在垃圾收集语言中,内存资源释放的处理方式与非内存资源释放不同。在C ++中,这些在RAII保护伞下是统一的。

答案 1 :(得分:0)

这是一种很好的做法。您应该始终初始化变量,即使它看起来没用。

这也适用于局部变量。这是一个很好的做法。

实际上,如果你这样做:

QString str;

然后str自动初始化。不幸的是,如果你这样做:

int value;

然后,值不会初始化为任何内容。它对速度有好处,但通常会导致错误。

对于构造函数,这是一个好主意,因为如果更改正文中的代码,最终可能无法初始化变量或其他...在列表中可能至少设置为null。初始化。

还有一个与异常相关联的原因,但这可能超出了Qt,它不会过多地使用异常。

答案 2 :(得分:0)

  

为什么在构造函数中将在代码中初始化时进行初始化?

我认为这只是因为如果实际的实例化后来推迟到另一个方法,对于intance,你将不会在某些操作中获得未初始化的成员,从而导致未定义的行为。

但是,在这种特殊情况下,如果不打算很快修改代码就没有多大意义。

它也可以归结为不同项目中的编码风格,但在这种特殊情况下,我不知道这受到官方Qt编码风格的限制。例如,在linux内核中,他们更喜欢 not 来像这样初始化它。