qt - 在父窗口/ widget类中初始化子窗口部件的目的是什么? [英] qt - what's the purpose of initialising child widgets in parent window/widget class?

查看:463
本文介绍了qt - 在父窗口/ widget类中初始化子窗口部件的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Qt中的VideoWidget和安全套接字客户端示例中,代码展示在父窗口小部件中的子窗口部件,例如:

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

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

但是,在代码下面,我看到以下内容:

  playButton = new QPushButton; 

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

  padLock = new QToolButton; 

为什么在构造函数中的initalise会在代码中被初始化?

解决方案


为什么在构造函数中的initalise会在代码中被初始化?




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

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

析构函数将删除 padLock ,但它有垃圾值,你有未定义的行为。回想一下,删除一个nullptr是安全的(就像在C!中调用 free(NULL))。垃圾挂锁值显示当您不初始化它时会发生什么。抛出表明一些干预代码可能抛出。具体来说,如果分配不成功,任何中间 new 都会抛出。 new 不会返回失败(如:它抛出 std :: bad_alloc 而不是返回,所以



如果一个人正在写惯用的C ++,那么指针不应该是裸露的指针,而是 QScopedPointer ,然后这个问题消失了。你不必记住将指针初始化为零,你不必记得清理它。 RAII给你很多的胜利。这是你真正使用C ++时的秘密武器。



C ++ RAII成语在任何其他常见程序中不存在语言。在允许它的语言(如Java,C#,F#,Python,OCaml和Common Lisp)中,惯用的解决方法是定义一个高阶 with_resource 函数,请参阅 OCaml Java Python Python 。基本上,在除C ++以外的语言中,尤其是在垃圾收集语言中,内存资源释放与非内存资源释放的处理不同。在C ++中,这些在RAII伞下统一。


In the VideoWidget and the Secure Socket Client examples in Qt, the code presented there initalises the child widgets in the parent widgets, like so:

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

and

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

However, further down the code, I see the following:

playButton = new QPushButton;

or in the case of the Secure Socket Client, this:

padLock = new QToolButton;

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

解决方案

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

So that the implementation is exception safe. Suppose that you'd have this code:

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

The destructor will delete padLock, but it has junk value, and you have undefined behavior. Recall that deleting a nullptr is safe (as is calling free(NULL) in C!). The junk padlock value shows what happens when you don't initialize it. Throwing demonstrates that some intervening code may throw. Specifically, any intervening new will throw if the allocation can't succeed. new does not return on failure (as in: it throws std::bad_alloc instead of returning, so the notion of return value doesn't apply at all).

If one is writing idiomatic C++, then the pointer should not be a naked pointer, but a QScopedPointer, and then this problem vanishes. You don't have to remember to initialize the pointer to zero, and you don't have to remember to clean it up. RAII gives you a lot of win. That's the secret weapon that you get when you really use C++ the way it's meant to be used.

The C++ RAII idiom doesn't exist per se in any other common programming language. In languages that allow it (such as Java, C#, F#, Python, OCaml, and Common Lisp), the idiomatic work-around is to define a higher-order with_resource function, see examples for OCaml, Java and Python and Python again. Basically, in languages other than C++, and especially in garbage-collected languages, memory resource deallocation is handled differently from non-memory resource deallocation. In C++, those are united under the RAII umbrella.

这篇关于qt - 在父窗口/ widget类中初始化子窗口部件的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆