5

来自 Symbian 世界,我习惯于尽可能多地使用堆以避免耗尽堆栈空间,尤其是在处理描述符时。CBase 派生类总是在堆上动态分配,因为如果不是,它们的成员变量将保持未初始化状态。相同的约定是否适用于 QObject 派生类?

在 Qt 中,将例如 QString 放在堆栈上似乎很常见。当 QString 充当堆栈上的容器时,字符串内容是否放在堆上,还是所有内容都放在堆栈上?

4

2 回答 2

10

正如 sje397 所说:将QString容器放在堆栈上是惯用的,因为它们是隐式共享的。它们的内部结构(pimpl idiom "d" 指针)是在堆上创建的。在堆上创建对象本身也没有意义。只会导致内存管理麻烦,并且在将指针传递给周围的字符串/容器时会丢失预期的写时复制属性。

QObjects另一方面,您几乎在所有情况下都希望在堆上创建,否则它们将立即再次被破坏。它们不能被复制或分配(好吧,可以为自己的子类强制执行它,但是QObject语义被破坏了),并且通常它们应该在它们被创建的方法体中继续存在。例外是QDialog,它通常在堆栈,然后是QDialog::exec,它会阻塞直到对话框关闭。但即使这样严格来说也是不安全的,因为外部事件(RPC 调用、后台操作)可能会导致对话框在 exec 返回之前被其父级(如果父级本身被删除)删除。然后在堆栈上创建对话框将在展开堆栈时导致双重删除 - >崩溃。

于 2010-08-05T09:48:57.767 回答
1

QString 和许多其他 Qt 类使用隐式数据共享。这意味着内存通常是在堆上分配的。

于 2010-08-05T07:34:04.357 回答