Qt中的数据结构是在堆上还是在栈上?

发布于 2024-11-07 13:40:34 字数 794 浏览 0 评论 0原文

我想知道 Qt 是否将以下代码的“版本 1”之类的内容放在堆上?在版本1中,dirStuff会被Qt放置在栈上还是堆上?我问这个问题是因为我有一种感觉,Java 将所有数据结构都放在堆上......不确定,因为我不记得曾经用 Java 考虑过这个问题。

版本 1

QFileInfoList dirStuff = dir.entryInfoList(QDir::Dirs | QDir::Files | 
                         QDir::NoDotAndDotDot | QDir::System | QDir::Hidden);

版本 2

QFileInfoList * dirStuff = new QFileInfoList();
*dirStuff = dir->entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot |
                                       QDir::System | QDir::Hidden);

当然,我假设版本 2 在堆上,但我想知道...

delete dirStuff;

是否真的会清理 dirStuff 的“版本 2”,因为它不是常规对象,而是可能是一个链接列表。我认为清理可能会有问题,所以我想知道是否有一种特殊的 Qt 方式我应该清理 Qt 数据结构,例如堆上的 QFileInfoList ...或者如果常规的旧 C++ 删除就足够了。

I'm wondering if Qt puts things like "version 1" of the below code on the heap? In version 1, would dirStuff be placed on the stack or the heap by Qt? I'm asking because I have a feeling that Java puts all data structures on the heap... Not sure cause I don't remember ever having to think about this with Java.

version 1

QFileInfoList dirStuff = dir.entryInfoList(QDir::Dirs | QDir::Files | 
                         QDir::NoDotAndDotDot | QDir::System | QDir::Hidden);

version 2

QFileInfoList * dirStuff = new QFileInfoList();
*dirStuff = dir->entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot |
                                       QDir::System | QDir::Hidden);

Of course, I'll assume that version 2 is on the heap, but I'm wondering if...

delete dirStuff;

would really clean up "version 2" of dirStuff because it is not a regular object but probably a linked list. The cleaning up of which I think could be problematic, so I'm wondering if there is a special Qt way I should be cleaning up a Qt data structure like a QFileInfoList on the heap... or if the regular old C++ delete is good enough.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

再可℃爱ぅ一点好了 2024-11-14 13:40:34

像 QList、QVector 等容器和像 QString、QByteArray、QFileInfo 等数据结构都可以使用 new/delete 在堆栈和堆上创建。删除总是足够的;任何需要的特殊清理都将封装在析构函数中。

也就是说,如果没有充分的理由使用堆(通常没有),我上面提到的所有类都应该在堆栈上创建。它们应该通过值/常量引用传递,而不是通过引用或指针传递。它们是隐式共享的(写时复制),这意味着未经修改的副本很便宜。与 java 不同,java 中几乎所有内容都通过引用传递,这里的对象是语义值。示例:

 //getter returns copy
 QList<Something> Foo::somethings() const {
     return m_somethings;
 }

 //list is passed by const reference to the setter 
 void Foo::setSomethings( const QList<Something>& l ) {
     m_somethings = l;
 }
 ...

 //Get the value of m_somethings, creating a (yet unmodified) copy. 
 QList<Something> list = somethings();
 //modify the copy. m_somethings is _not_ modified (different object).  
 list.append( Something( "Something else" ) );
 //Write changes back to m_somethings
 setSomethings( list );

另请参阅此答案 一个类似的问题,解释为什么 QObjects 不同。

Containers like QList, QVector etc. and data structures like QString, QByteArray, QFileInfo... can be created both on the stack and on the heap with new/delete. delete is always enough; Any special cleanup needed would be encapsulated in the destructor.

That said, all the classes I mentioned above should be created on the stack if there is not a strong reason for the heap (and there usually isn't). They are supposed to be passed by value/const reference instead of by reference or pointer. They are implicitely shared (copy-on-write), which means copies without modification are cheap. Opposed to java, where you pass almost everything by reference, here the objects are semantical values. Example:

 //getter returns copy
 QList<Something> Foo::somethings() const {
     return m_somethings;
 }

 //list is passed by const reference to the setter 
 void Foo::setSomethings( const QList<Something>& l ) {
     m_somethings = l;
 }
 ...

 //Get the value of m_somethings, creating a (yet unmodified) copy. 
 QList<Something> list = somethings();
 //modify the copy. m_somethings is _not_ modified (different object).  
 list.append( Something( "Something else" ) );
 //Write changes back to m_somethings
 setSomethings( list );

See also this answer to a similar question, explaining why QObjects are different.

蒲公英的约定 2024-11-14 13:40:34

在版本 1 中,对象将被放入堆栈中,但它可能在内部指向堆中分配的数据(如果它在其方法内部动态分配内存)。

关于版本 2,delete 会清理它,因为它调用 QFileInfoList 的析构函数,其中 Qt 库会执行必要的操作来删除不再使用的所有资源。

In version 1, the object will be put on the stack, but it may internally point to data allocated in the heap (if it dynamically allocates memory inside its methods).

About version 2, delete would clean it up because it calls QFileInfoList's destructor, in which the Qt library does what's necessary to remove every resource that won't be used anymore.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文