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

时间:2011-05-18 02:18:21

标签: qt

我想知道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方式我应该清理堆上的QFileInfoList的Qt数据结构...或者如果常规的C ++删除就足够了。

2 个答案:

答案 0 :(得分:3)

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

关于版本2,delete会清理它,因为它调用了QFileInfoList的析构函数,其中Qt库执行了删除不再使用的每个资源所需的内容。

答案 1 :(得分:3)

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

那就是说,如果堆没有强大的理由(通常没有),我上面提到的所有类都应该在堆栈上创建。它们应该通过值/ const引用而不是通过引用或指针传递。它们被隐含地共享(写时复制),这意味着没有修改的副本便宜。反对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 );

另见this answer一个类似的问题,解释为什么QObjects不同。