将派生类的unique_ptr添加到基类unique_ptr的向量中

时间:2016-11-09 15:32:06

标签: c++ inheritance vector move-semantics unique-ptr

我有一个unique_ptr,我想添加到矢量>。

unique_ptr<Derived> derivedObject;
vector<unique_ptr<Base>> vec;

vec.push_back(derivedObject) // Invalid arguments

3 个答案:

答案 0 :(得分:8)

unique_ptr保证它只有一个指向内存的指针,所以你不能只将它复制到向量中,你需要移动它:

vec.push_back(std::move(derivedObject));

如果你看一下unique_ptr构造函数(http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr),你看,这个类没有实现复制构造函数,而是实现了移动构造函数(http://en.cppreference.com/w/cpp/language/move_constructor)。

答案 1 :(得分:3)

这是因为您无法复制std::unique_ptr。使用std::move()

可解决此问题
#include <iostream>
#include <memory>
#include <vector>

struct Base {
};

struct Derived : public Base {
};

int main()
{
    std::unique_ptr<Derived> derivedObject;
    std::vector<std::unique_ptr<Base>> vec;

    vec.push_back(std::move(derivedObject));    
               // ^^^^^^^^^^             ^
}

这是live demo

答案 2 :(得分:1)

cppreference about unique_ptr

  

如果T是某个基数B的派生类,那么std :: unique_ptr&lt; T>可隐式转换为std :: unique_ptr&lt; B&gt ;.

所以,问题不在于转换失败。

  

该类满足MoveConstructible和MoveAssignable的要求,但不满足CopyConstructible或CopyAssignable的要求。

这是导致失败的原因。 unique_ptr可以移动但不能复制,因为这会破坏单一所有权协议。

所以要么使用std::move,要么直接使用make_derived

vec.push_back(std::move(derivedObject));  //Option 1. When unique_ptr is already created.
OR,
vec.push_back(make_unique<Derived>());    //Option 2. New unique_ptr

使用选项#2,您可以避免拥有本地变量。无论如何,在move上执行unique_ptr时,unique_ptr拥有的对象都会被处置。 Demo.