[英]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_ptr
或QScopedPointer
,然后這個問題就會消失。 您不必記住將指針初始化為零,並且您不必記得清理它。 RAII為您贏得了很多勝利。 這是你真正使用C ++的秘密武器。
C ++ RAII習語本身並不存在於任何其他常見的編程語言中。 在允許它的語言中(例如Java,C#,F#,Python,OCaml和Common Lisp),慣用的解決方法是定義更高階的with_resource
函數, 再次參見OCaml , Java和Python以及Python的示例。 基本上,在C ++以外的語言中,特別是在垃圾收集語言中,內存資源釋放的處理方式與非內存資源釋放不同。 在C ++中,這些在RAII保護傘下統一起來。
這是一種很好的做法。 您應該始終初始化變量,即使它看起來沒用。
這也適用於局部變量。 這是一個很好的做法。
實際上,如果你這樣做:
QString str;
然后str自動初始化。 不幸的是,如果你這樣做:
int value;
然后,值不會初始化為任何內容。 它對速度有好處,但通常會導致錯誤。
在構造函數的情況下,這是一個好主意,因為如果您更改正文中的代碼,您可能最終不會初始化變量或其他...在初始化程序列表中至少可以設置為null。
鏈接異常也有一個原因,但這可能超出了Qt,它不會過多地使用異常。
為什么在構造函數中將在代碼中初始化時進行初始化?
我相信這只是因為如果實際的實例化后來被推遲到另一個方法,對於intance,你將不會在某些操作的中間獲得未初始化的成員導致未定義的行為。
但是,在這種特殊情況下,如果不打算很快修改代碼,則沒有多大意義。
它也可以歸結為不同項目中的編碼風格,但在這種特殊情況下,我不知道這受到官方Qt編碼風格的限制。 例如,在linux內核中,他們不喜歡像這樣初始化它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.