我想知道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 ++删除就足够了。
答案 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不同。