【问题标题】:c++ unique_ptr inside vector with inheritance时间:2019-05-10 标签:c++unique_ptr inside vector with继承
【发布时间】:2015-04-29 12:19:21
【问题描述】:

我正在使用不同的智能指针并遇到了问题。

我有一个Environment 抽象类和一个继承Environment 的基础类:

class Ground : public Environment
{
protected:
    std::string type;
    int damage;

public:
    Ground() : Environment()
    {
        this->type = "ground";
    }

    virtual void SetDamage(int _damage)
    {
        this->damage = _damage*5;
    }

    virtual std::string& GetType()
    {
        return this->type;
    }

    virtual int GetDamage()
    {
        return this->damage-10;
    }

    virtual ~Ground(){}
};

我还有一个Dirt 类,它继承了Ground 类:

class Dirt : public Ground
{
public:
    Dirt() : Ground()
    {
        this->type = "dirt";
    }

    void SetDamage(int _damage)
    {
        this->damage = _damage*6;
    }

    int GetDamage()
    {
        return this->damage-20;
    }

    ~Dirt()
    {

    }


private:

};

现在,如果我想像这样在std::vector 中使用它:

std::vector<std::unique_ptr<Ground>> listGround;

std::unique_ptr<Ground> ground(new Ground());
listGround.push_back(ground);

std::unique_ptr<Dirt> dirt(new Dirt());
listGround.push_back(dirt); // FAIL

for (auto i = listGround.begin(); i != listGround.end(); i++)
{
    (*i)->SetDamage(80);
    std::cout << (*i)->GetType() << " " << (*i)->GetDamage() << std::endl;
}

listGround.empty();

我收到一个编译错误,说没有可用的用户定义转换运算符可以在上面代码中标记为 FAIL 的行上执行此转换等。

如果我使用std::shared_ptr,一切都会按预期进行。原始指针也是如此。

为什么会出现这个错误?

错误 C2664: 'void std::vector<_ty>::push_back(std::unique_ptr &&)' : 无法将参数 1 从 'std::unique_ptr<_ty>' 转换为 'std::unique_ptr<_ty> &&' 1> with 1> [ 1>
_Ty=std::unique_ptr 1> ] 1> and 1> [ 1> _Ty=Dirt 1> ] 1> and 1> [ 1> _Ty=接地 1> ] 1> 原因:不能 从 'std::unique_ptr<_ty>' 转换为 'std::unique_ptr<_ty>' 1>
与 1> [ 1> _Ty=污垢 1> ] 1>
和 1> [ 1> _Ty=接地 1> ] 1>
没有可以执行此操作的用户定义的转换运算符 转换,否则无法调用操作符

【问题讨论】:

  • 能否请您添加确切的编译器错误?
  • 你需要做listGround.push_back(std::move(ground));
  • 谢谢队友,当我试图将一些东西插入向量中时,当 IDE 只是将新的污垢标记为错误而不是两行时,我感到很困惑

标签: c++ c++11 smart-pointers


【解决方案1】:

就地创造事物:

listGround.emplace_back(new Dirt());

这不是shared_ptr,但您尝试在dirtlistGround.back() 之间共享所有权

【讨论】:

  • 花了我 5 分钟来了解所有权,有点慢。清除那里的一切,伙计。
【解决方案2】:

std::vector::push_back 要求传递的类型是可复制的(或在 C++11 中是可移动的),而 std::unique_ptr 是不可复制的。这就是错误消息告诉您的内容,它缺少相应的移动转换。您可以使用 std::move 函数移动 std::unique_ptr,该函数只需将适当的转换为正确的 r 引用类型。

【讨论】:

  • 其实只需要可移动,不能复制。由于unique_ptr 是可移动的,因此存在重大差异。
  • 我没有看到他的错误信息是针对移动版本的。我的答案以前对 C++03 是正确的,但我已经用 C++11 的移动语义对其进行了更新。
  • 好吧,在 C++11 之前并没有 std::unique_ptr。 C++03 有臭名昭著的auto_ptr,而用std::unique_ptr 替换它的能力是移动语义的一个激励因素。
  • std::tr1::unique_ptr 在 C++11 之前就存在了,许多人也从 boost 中使用它,一些编译器在 C++11 之前的 std 命名空间中暴露了 tr1 unique_ptr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 2020-10-01
相关资源
最近更新 更多