C++ 从存储派生类的基类的向量实例化派生类的唯一_ptr
考虑以下代码:C++ 从存储派生类的基类的向量实例化派生类的唯一_ptr,c++,oop,c++11,inheritance,unique-ptr,C++,Oop,C++11,Inheritance,Unique Ptr,考虑以下代码: struct Fruit { Fruit() {} virtual ~Fruit() {} std::string name; }; struct Banana : public Fruit { std::string color; }; struct Pineapple : public Fruit { int weight; }; 这是我的主要观点: intmain() { 向量积; product.push_back(st
struct Fruit
{
Fruit() {}
virtual ~Fruit() {}
std::string name;
};
struct Banana : public Fruit
{
std::string color;
};
struct Pineapple : public Fruit
{
int weight;
};
这是我的主要观点:
intmain()
{
向量积;
product.push_back(std::unique_ptr(新香蕉));//产品[0]是香蕉
新菠萝;
//我需要访问产品[0]的“颜色”成员
std::unique_ptr b=std::move(产品[0]);//这不起作用,为什么?
自动c=b->颜色;
}
在
产品[0]
中,我将唯一的\u ptr存储到香蕉,为什么我不能将其分配到香蕉唯一的\u ptr 您需要显式强制转换,因为第一个产品可以是任何水果。。。编译器不知道这种水果是香蕉还是菠萝
正如@IgorTandetnik所说,你可以做到:
std::unique_ptr<Banana> b{static_cast<Banana*>(product[0].release())};
std::unique_ptr b{static_cast(产品[0].release())};
在何处使用,以及
注意:您不能退回到对b使用
auto
,因为编译器将选择struct Fruit
作为类型,以便为任何子类做好准备。您不希望所有权转移,所以只强制转换指针:
auto& banana = dynamic_cast<Banana&>(*product[0]);
auto c = b->color;
auto&banana=dynamic_cast(*产品[0]);
自动c=b->颜色;
如果您确实确定水果
真的是一个香蕉
,则可以将动态
替换为静态
。
如果您的错误,static\u cast
将导致UB,而您可以使用dynamic\u cast
检查有效性(cast-to-reference或null-pointer with-cast-to-pointer除外)。编译器不知道产品[0]
指向香蕉,而不是其他水果。如果您确信这一点,可以通过强制转换的方式告诉编译器。例如,std::unique_ptr b{static_cast(产品[0].release())}代码>使用release()我的产品[0]丢失。我不希望这种情况发生,因为我计划再次使用它。还有其他方法吗?如果使用std::unique\u ptr b=std::move(产品[0]),它也会丢失代码>,如果它要编译,那么我假设这就是您想要的。如果您不想夺走向量的所有权,请使其auto b=static_cast(产品[0].get())代码>使用release()我的产品[0]将永远丢失。我不希望这种情况发生,因为我计划再次使用它。还有其他方法吗?@Gaetan应该只有一个唯一的\u ptr
指向给定的对象。如果它是本地的std::unique\u ptr b
,那么它就不能是产品的std::unique\u ptr
元素。也许你只想要一个香蕉*b
?哦,是的,有了香蕉*b,一切都很好。谢谢因此,如果不将现有的unique_ptr设置为nullptr,unique_ptr就不能与现有的unique_ptr实例化,对吗?@Gaetanunique_ptr
是唯一的,即它不能共享所有权。这就是为什么不可能复制它,例如,所以是的。
auto& banana = dynamic_cast<Banana&>(*product[0]);
auto c = b->color;