2016-03-07 59 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'的新实例本身。 –

相关问题