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

标签 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;

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

最佳答案

Why initalise in the constructor when it will be initalised in the code?

这样实现是异常安全的。假设您有以下代码:

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++ 的使用方式使用它时,这就是您获得的 secret 武器。

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

关于c++ - qt - 在父窗口/小部件类中初始化子小部件的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21964662/

相关文章:

c++ - DLL 需要访问其应用程序的符号

ios - Swift:初始化数据并将其发送到不同的 Controller

swift - 通过调用 super : call can throw but is not marked with `try` 覆盖所需的 init

c++ - 如何给QListWidget分配一个特定的数字,以便以后修改?

qt - 如何在Qt Creator 中设置Qdialog 的固定高度尽可能小和扩展的宽度?

c++ - 初始化类的静态非常量数据成员

c++ - future 和 shared_future 有什么区别?

c++ - 在保证复制省略的情况下,为什么需要完全定义类?

c++ - 使用 BOOST shared_array 而不是 shared_ptr 的好处

qt - 在使用亚洲语言输入文本时,在 OSX 上调出一个用于文本输入的输入窗口