qt - what's the purpose of initialising child widgets in parent window/widget class?

无人久伴 提交于 2019-12-13 15:01:47

问题


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?


回答1:


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 std::unique_ptr or 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.




回答2:


It is good practice. You should always initialize your variables, even if it looks useless.

This goes for local variables too. It is a good practice.

Actually, if you do this:

QString str;

Then str is automatically initialized. Unfortunately, if you do this:

int value;

Then value is not initialized to anything. It's good for speed, but can often lead to bugs.

In case of a constructor, it is a good idea because if you change the code in the body, you may end up not initializing a variable or another... which could have been at least set to null in the list of initializers.

There is also a reason in link with exceptions, but that's probably beyond Qt which doesn't use exceptions much.




回答3:


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

I believe it is just for the reason that if the actual instantiation is deferred to a different method later, for intance, you will not get an uninitialized member in the middle of some operation causing undefined behavior.

However, in this particular case, it does not make much sense if the code is not planned to be modified any soon.

It might also boil down to coding styles in different projects, but in this special case, I am not aware of this being constrained by the official Qt coding style. For instance, in the linux kernel, they prefer not to initialize it like this.



来源:https://stackoverflow.com/questions/21964662/qt-whats-the-purpose-of-initialising-child-widgets-in-parent-window-widget-cl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!