簡體   English   中英

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

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

在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;

為什么在構造函數中將在代碼中初始化時進行初始化?

為什么在構造函數中將在代碼中初始化時進行初始化?

這樣實現是異常安全的。 假設你有這個代碼:

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函數, 再次參見OCamlJavaPython以及Python的示例。 基本上,在C ++以外的語言中,特別是在垃圾收集語言中,內存資源釋放的處理方式與非內存資源釋放不同。 在C ++中,這些在RAII保護傘下統一起來。

這是一種很好的做法。 您應該始終初始化變量,即使它看起來沒用。

這也適用於局部變量。 這是一個很好的做法。

實際上,如果你這樣做:

QString str;

然后str自動初始化。 不幸的是,如果你這樣做:

int value;

然后,值不會初始化為任何內容。 它對速度有好處,但通常會導致錯誤。

在構造函數的情況下,這是一個好主意,因為如果您更改正文中的代碼,您可能最終不會初始化變量或其他...在初始化程序列表中至少可以設置為null。

鏈接異常也有一個原因,但這可能超出了Qt,它不會過多地使用異常。

為什么在構造函數中將在代碼中初始化時進行初始化?

我相信這只是因為如果實際的實例化后來被推遲到另一個方法,對於intance,你將不會在某些操作的中間獲得未初始化的成員導致未定義的行為。

但是,在這種特殊情況下,如果不打算很快修改代碼,則沒有多大意義。

它也可以歸結為不同項目中的編碼風格,但在這種特殊情況下,我不知道這受到官方Qt編碼風格的限制。 例如,在linux內核中,他們喜歡像這樣初始化它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM