2016-03-07 87 views
0

我有一個std::vector<std::unique_ptr<T>> vec1其中T是一個抽象類型。我想創建std::vector<T*> vec2,其中來自第二個向量的指針指向的對象是由第一個向量指針指向的對象的副本。如何將矢量<unique_ptr <T>>複製到獨立矢量<T*>

因此,例如:*(vec1[0]) == *(vec2[0])vec1[0].get() != vec2[0] ...等...

如何做到這一點?

+0

究竟是什麼問題?你不知道如何從'unique_ptr'獲得底層指針?或者是其他東西? – SergeyA

+0

@SergeyA。我知道很熱從'std :: unique_ptr'('get()'方法)獲取原始指針。但是如果我將它推到vec2那麼vec2將不會獨立於vec1。來自vec1的指針將指向與來自vec2的指針相同的內存位置。我需要複製對象。 – peter55555

+0

爲什麼?這是一個巨大的代碼氣味。 C API採用'T **'和所有權? :( –

回答

5

使用std::transform

std::vector<T*> vec2; 
vec2.reserve(vec1.size()); // optimization to avoid reallocations, it isn't necessary, and without it the code still works correctly 
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), [](const std::unique_ptr<T>& p){ return YourCloneFunction(*p); } 

一種方法寫一個克隆功能是讓你的所有子類都定義的虛擬clone功能,這在T中是抽象的。這種方法的代碼很簡單,但需要爲每個Derived類定義。

class T 
{ 
    virtual std::unique_ptr<T> clone() const = 0; 
    virtual ~T(){} 
}; 

class Derived : public T 
{ 
    std::unique_ptr<T> clone() const override { 
     return std::unique_ptr<T>(new Derived(*this)); 
    } 
}; 

這樣,代碼變得

std::vector<T*> vec2; 
vec2.reserve(vec1.size()); // optimization to avoid reallocations, it isn't necessary, and without it the code still works correctly 
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), [](const std::unique_ptr<T>& p){ return p->clone().release(); } 

需要注意的是,我們有vec2指向不受任何智能指針擁有的對象原始指針。這很糟糕,除非您將vec2傳遞給接受這些指針所有權的傳統函數。

否則,如果你想只有std::vector<T*>鑑於拷貝,克隆成中間std::vector<std::unique_ptr<T>>,然後在每個實例複製的.get()結果std::vector<T*>

+0

,因爲它是一個副本,您應該在變換之前顯示適當大小的保留行爲的良好行爲 – galop1n

+1

爲什麼要放棄這個需求?真的沒有理由在這裏調用'reserve'。 – SergeyA

+3

沒有它,它是正確的,這是一個優化 – milleniumbug

0

手動方式:

std::vector<std::unique_ptr<T>> vec1; 
std::vector<T*> vec2; 
vec2.reserve(vec1.size()); // optimization to avoid reallocations 

for (const auto& e : vec1) { 
    vec2.push_back(e->clone()); 
} 

virtual T* T::clone() const

+1

因爲它是一個副本,你應該顯示良好的行爲調用儲備在循環前的正確大小 – galop1n

+0

@ galop1n,沒有真正的需要。 – SergeyA

+0

「* T是一個抽象類型*」,這意味着你不能構造'T'的新實例本身。 –

相關問題