非QObject派生的类应“始终"使用吗?被放在堆栈上? [英] Should non-QObject derived classes "always" be put on the stack?

查看:109
本文介绍了非QObject派生的类应“始终"使用吗?被放在堆栈上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Coming from the Symbian world, I'm used to using the heap as much as possible to avoid running out of stack space, especially when handling descriptors. CBase derived classes were always dynamically allocated on the heap, since if they were not, their member variables would stay uninitialized. Does the same convention apply to QObject-derived classes?

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

In Qt it seems to be common to put, for example QString, on the stack. Are the string contents put on the heap while QString acts as a container on the stack, or is everything put on the stack?

推荐答案

正如sje397所说:将QString和容器隐式共享是一种习惯.它们的内部(pimpl惯用语"d"指针)在堆上创建.同样,在堆上创建对象本身也没有意义.只会造成内存管理的麻烦,并且在将指针传递到字符串/容器周围时,您将失去预期的写时复制属性.

As sje397 said: It's idiomatic to put QString and containers on the stack, as they are implicitly shared. Their internals (pimpl idiom "d" pointer) are created on the heap. There is no point in creating the object itself on the heap, too. Just causes memory-management hassles and you lose the intended copy-on-write properties when passing pointers to strings/containers around.

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

QObjects on the other hand you want to create on the heap in almost all cases, as otherwise they would be destructed again right away. They can't be copied or assigned (well, one can enforce it for own subclasses, but the QObject semantics are broken then), and usually they are supposed to survive the method body they are created in. Exception is QDialog, which is often created on the stack, followed by QDialog::exec, which blocks until the dialog is closed. But even that is strictly spoken unsafe, as external events (RPC calls, background operations) could cause the dialog to be deleted by its parent (if the parent itself is deleted) before exec returns. Then having the dialog created on the stack will cause double deletion when unwinding the stack -> crash.

这篇关于非QObject派生的类应“始终"使用吗?被放在堆栈上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆