我有一個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]
...等...
如何做到這一點?
我有一個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]
...等...
如何做到這一點?
使用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*>
,因爲它是一個副本,您應該在變換之前顯示適當大小的保留行爲的良好行爲 – galop1n
爲什麼要放棄這個需求?真的沒有理由在這裏調用'reserve'。 – SergeyA
沒有它,它是正確的,這是一個優化 – milleniumbug
手動方式:
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
究竟是什麼問題?你不知道如何從'unique_ptr'獲得底層指針?或者是其他東西? – SergeyA
@SergeyA。我知道很熱從'std :: unique_ptr'('get()'方法)獲取原始指針。但是如果我將它推到vec2那麼vec2將不會獨立於vec1。來自vec1的指針將指向與來自vec2的指針相同的內存位置。我需要複製對象。 – peter55555
爲什麼?這是一個巨大的代碼氣味。 C API採用'T **'和所有權? :( –