來自Symbian世界,我習慣於儘可能多地使用堆以避免堆棧空間用盡,特別是在處理描述符時。 CBase派生類總是在堆上動態分配,因爲如果它們不是,它們的成員變量將保持未初始化狀態。相同的約定是否適用於QObject派生類?非QObject派生類應該總是放在堆棧上嗎?
在Qt中,通常會在堆棧中放置例如QString。 QString作爲堆棧中的容器,還是放置在堆棧上的所有內容都將字符串內容放在堆上?
來自Symbian世界,我習慣於儘可能多地使用堆以避免堆棧空間用盡,特別是在處理描述符時。 CBase派生類總是在堆上動態分配,因爲如果它們不是,它們的成員變量將保持未初始化狀態。相同的約定是否適用於QObject派生類?非QObject派生類應該總是放在堆棧上嗎?
在Qt中,通常會在堆棧中放置例如QString。 QString作爲堆棧中的容器,還是放置在堆棧上的所有內容都將字符串內容放在堆上?
正如sje397所說:將QString
和容器放在堆棧上是慣用的,因爲它們是隱含共享的。他們的內部(pimpl習語「d」指針)在堆上創建。在堆上創建對象本身也沒有意義。只是導致內存管理麻煩,並且在傳遞指向字符串/容器的指針時丟失了預期的寫入時複製屬性。
QObjects
另一方面,你想在幾乎所有情況下在堆上創建,否則它們將立即再次被破壞。它們不能被複制或分配(好吧,可以爲自己的子類強制執行它,但是QObject
語義會被破壞),並且通常它們應該在創建它們的方法體中存在。 例外是QDialog
,它是通常在堆棧上創建,然後是QDialog::exec
,這會阻塞,直到對話框關閉。但即使這樣做也是不安全的,因爲外部事件(RPC調用,後臺操作)可能會導致在exec返回之前父對象被刪除(如果父對象本身被刪除)。 然後在堆棧上創建對話框時,會導致雙重刪除 - >崩潰。
QString和許多其他Qt類,使用implicit data sharing。這意味着內存通常分配在堆上。
感謝您的廣泛答覆。它和sje397的鏈接清除了我的困惑。 – fejd 2010-08-05 10:57:40