2013-01-14 24 views
4

我對Qt的foreach函數有點問題。我有一個類短語,它是QList的一個子類。在〜短語中,我刪除了所有GlossItem指針。Qt的foreach表達式需要深度複製嗎?

在通過樂句GlossItem指針迭代,我想用Qt的的foreach:

// phrase is a pointer to a Phrase object, 
    // which is a subclassed QList<GlossItem*> 
    foreach(GlossItem *glossItem , *phrase) 
    { 
     // use glossItem 
    } 

出於某種原因的foreach正在執行對短語深拷貝(我知道這是因爲它要求我執行復制構造函數)。但是,如果有短語的副本 - 並且我不想創建每個GlossItem的深層副本 - 這意味着這些指針將被刪除兩次。 (或者,刪除一次,然後崩潰。)所以我必須使用這個,它可以工作,但不那麼漂亮。

for(int i=0; i<phrase->count(); i++) 
    { 
     GlossItem *glossItem = phrase->at(i); 
     // use glossItem 
    } 

有沒有辦法解決這個問題,還是我只需要忍受它呢?

+1

在你的第一個例子中,你使用了一個索引變量'i' - 哪裏適合? –

+2

此外,我沒有看到任何證據表明'QList'有一個虛擬析構函數,它允許你從它繼承。 –

+0

這不是一個好設計:容器意味着被複制,刪除其中的內容將會破壞(使用Q_DISABLE_COPY來防止複製)。正如託尼所說,QList沒有虛擬驅動器,所以從它繼承並不是一個好主意。設計提示:永遠不要從容器繼承,而是使它們成爲某些包裝類的成員。類短語{QList list()const; ... Q_DISABLE_COPY(Phrase)}; –

回答

6

從文檔

當它進入一個foreach循環的Qt自動進行容器的副本。

因爲的foreach創建容器的一個副本,使用了可變非const引用不允許修改原來的容器。

因此,我認爲你的具體使用情況foreach不適合,否則你結束與Phrase的全新副本額外的指針,而不是返回所需的實際原Phrase

+1

我從未意識到這一點 - 乍一看實施foreach的可怕方式。爲什麼巨魔做出這個決定?如果迭代器被要求是一個常量引用,那麼人們有機會注意到這種意外的行爲,但是它的實現方式,只有在迭代了默認拷貝contstructor所拷貝的東西之後,纔會注意到。 – Jens

1

不,如果你從foreach擴大代碼:qt.gitorious.org/qt/qt/blobs/HEAD/src/corelib/global/qglobal.h#line2371 它使用常量性。是的,它會複製容器,但因爲Qt中的所有容器類都是隱式共享的,所以它只是淺拷貝,而不是深層拷貝。