2012-09-02 52 views
2

什麼是正確的做法?我知道如果容器是基類值類型,那麼存儲的派生對象是'切片'。如果容器是派生類類型的,則不能存儲基類對象。對?存儲基本和派生對象的混合的容器?

如果要使用指針,auto_ptr不能使用,因爲它有複製語義問題。 shared_ptr是解決這個問題的唯一解決方案嗎?

任何人都可以提供解決此問題的更多詳細信息,示例代碼或在線文章?這應該是一個相當普遍的問題,但是我沒有在教科書或在線上找到關於它的很多信息。

在此先感謝。

btw,我只是搜索unique_ptr。它似乎不支持複製語義。因此,在STL中使用auto_ptr並非只是安全的,但可能由於缺乏複製語義,許多STL操作或算法不能用於unique_ptr容器?

回答

2

最明顯的解決方案是使用std::unique_ptr

class IBase {}; 
class Derived : virtual public IBase {}; 
std::vector<std::unique_ptr<IBase>> v; 
v.push_back(std::unique_ptr<IBase>(new Derived())); 

你可以使用std::shared_ptr,但它的所有權語義顯著改變程序的行爲,保持動態分配的對象活着的生命,直到沒有人擁有對它們的引用。

+0

感謝juanchopanza,你能詳細解釋一下'但是它的所有權語義大大改變了程序的行爲,保持......'嗎?你的意思是,如果程序員不太在意,使用shared_ptr有時會留下未使用的副本,因此該對象不能及時釋放;而unique_ptr總是有單個副本,並沒有這樣的問題? – user1559625

+0

@ user1559625 [this so question](http://stackoverflow.com/questions/6876751/differences-between-unique-ptr-and-shared-ptr)可能有所幫助。基本上,unique_ptr具有指針對象的所有權,並在被刪除時將其刪除。所有權可以從一個unique_ptr「移動」到另一個,但永遠不會有多個所有者。通過shared_ptr,可以有任意數量的所有者,最後一個將會刪除指針。有時候,你想知道指針被刪除的時間,其他時間你不關心。 – juanchopanza

+0

我覺得'IBase'必須有一個虛擬析構函數。使用'shared_ptr'由於刪除器的類型擦除而不是問題;但'unique_ptr'不是這種情況。 – rodrigo

5

如果你想要多態行爲(你確實需要它),那麼你必須使用指針或引用。這在許多地方都有很好的記錄。

既然你不能使用容器的引用,你必須使用指針的容器。

現在,您可以使用您認爲合適的任何類型的指針:unique_ptr,shared_ptr或原始指針。

+2

的確,您無法創建引用的容器。但你可以用'std :: reference_wrapper '來僞造它。它包含一個指針,但可以通過引用訪問它。 –

+0

有沒有辦法知道算法是否可以安全地使用'unique_ptr'?顯然有些不能('copy()','fill()'),但它看起來像刪除或重新排列元素可能會或可能不會,這取決於它們如何實現。 –

+1

@PeteBecker:我嘗試過'reference_wrapper'事物的容器,並且它不能很好地工作。問題是,在C++中,你不能重載'operator.',所以爲了訪問包含對象的成員,你必須做的,例如'c [0] .get() - > member'。如果你必須這樣做,你可以做'c [0] - > member'。 – rodrigo

2

有std :: vector和std :: shared_ptr的例子。我認爲這就是你想要的。

#include <iostream> 
#include <memory> 
#include <vector> 

class Base { 
public: 
    virtual void foo() { 
     std::cout << "base" << std::endl; 
    } 
}; 

class Derived : public Base { 
    void foo() { 
     std::cout << "derived" << std::endl; 
    } 
}; 

int main() 
{ 
    std::vector<std::shared_ptr<Base> > v; 
    v.push_back(std::shared_ptr<Base>(new Base)); 
    v.push_back(std::shared_ptr<Base>(new Derived)); 

    for (auto it : v) { 
     it->foo(); 
    } 
} 
+0

這裏不清楚是否需要共享所有權。我會說,最好使用獨特的所有權*除非*明確關心共享。 – juanchopanza

+0

我的問題也是,所以什麼時候共享所有權是必須的? – user1559625

0

[http://www.boost.org/doc/libs/1_51_0/libs/ptr_container/doc/ptr_container.html](The升壓指針容器庫)是隻爲這製成。

+0

謝謝。非常有用的信息。 – user1559625

相關問題