C++ Qt';s foreach表达式需要深度副本吗?

C++ Qt';s foreach表达式需要深度副本吗?,c++,qt,foreach,C++,Qt,Foreach,我对Qt的foreach函数有点问题。我有一个类短语,它是QList的一个子类。在~短语中,我删除了所有的GlossItem指针 在迭代短语中的GlossItem指针时,我想使用Qt的foreach: // phrase is a pointer to a Phrase object, // which is a subclassed QList<GlossItem*> foreach( GlossItem *glossItem , *phrase )

我对Qt的foreach函数有点问题。我有一个类短语,它是QList的一个子类。在~短语中,我删除了所有的GlossItem指针

在迭代短语中的GlossItem指针时,我想使用Qt的foreach:

    // phrase is a pointer to a Phrase object, 
    // which is a subclassed QList<GlossItem*>
    foreach( GlossItem *glossItem , *phrase )
    {
        // use glossItem
    }
//短语是指向短语对象的指针,
//这是一个子类QList
foreach(GlossItem*GlossItem,*短语)
{
//使用glossItem
}
出于某种原因,foreach正在对短语执行深度复制(我知道这一点,因为它需要我实现复制构造函数)。但如果有短语的副本——如果我不想创建每个GlossItem的深层副本——这意味着这些指针将被删除两次。(或者,删除一次,然后崩溃。)所以我必须使用这个,它可以工作,但不太漂亮

    for(int i=0; i<phrase->count(); i++ )
    {
        GlossItem *glossItem = phrase->at(i);
        // use glossItem
    }
for(int i=0;icount();i++)
{
GlossItem*GlossItem=短语->在(i)处;
//使用glossItem
}
有办法解决这个问题吗?还是我只需要接受它?

来自文档

当容器进入foreach循环时,Qt自动获取容器的副本

由于foreach创建容器的副本,因此使用变量的非常量引用不允许修改原始容器


因此,我认为对于您的特定用例,
foreach
是不合适的,否则您最终会得到带有附加指针的
短语的新副本,而不是返回您想要的实际原始
短语

否,如果您查看从foreach展开的代码:qt.gitorious.org/qt/qt/blobs/HEAD/src/corelib/global/qglobal.h#line2371
它使用常量迭代器。是的,它确实复制了容器,但由于Qt中的所有容器类都是隐式共享的,所以它只是浅层复制,而不是深度复制。

在第一个示例中,您使用了一个索引变量
i
-这在哪里合适?而且,我没有看到任何证据表明
QList
具有虚拟析构函数,这不是一个好的设计:容器是要被复制的,删除它在dtor中的内容会被破坏(使用Q_DISABLE_COPY来防止复制)。正如Tony所说,QList没有虚拟dtor,因此继承它不是一个好主意。设计提示:永远不要从容器继承,而是让它们成为某个包装类的成员。类短语{QList()const;…Q_DISABLE_COPY(短语)};该索引变量是一个复制/粘贴错误,即我编辑的组件10。谢谢你的设计意见,弗兰克。当我第一次编写此代码时,我对QList的子类化表示怀疑,但现在我有了不这样做的具体原因。我从未意识到这一点——乍一看,这是一种可怕的foreach实现方式。巨魔为什么做出这个决定?如果迭代器被要求是const ref,人们可能会注意到这种意外的行为,但是按照它的实现方式,在迭代默认的copy contstructor无法复制的内容之前,您不会注意到。