[英]Can't avoid object slicing in c++
我想构造一个std::vector
包含从Base
class 派生的对象。 我知道我不能直接将整个 object 推入vector
中(由于 object 切片)所以我使用智能指针。 但是,它仍然不起作用。 我究竟做错了什么?
我的代码:
struct Base{
int num1;
explicit Base(int num1){
this->num1 = num1;
}
};
struct Derived : Base{
int num2;
explicit Derived(int num1, int num2) : Base(num1){
this->num2 = num2;
}
};
int main()
{
std::vector<std::unique_ptr<Base>> someList;
someList.push_back(std::make_unique<Derived>(100, 1));
someList.push_back(std::make_unique<Derived>(100, 2));
std::cout << someList[0]->num2 << std::endl; // <---- Can't access num2 !
}
Derived
对象及其num2
成员在那里,但类型系统不知道这一点(在类似的代码中,可能不确定)。
someList[0]
的类型是std::unique_ptr<Base>
,因此->
运算符允许命名Base
的成员。 一般来说, unique_ptr<Base>
可能根本不指向Derived
,所以这是安全的方法。
如果Base
类型是多态的,您可以使用dynamic_cast
检查 object 是否真的是Derived
。 为了让它工作,让我们向Base
添加一个虚拟析构函数:
struct Base{
int num1;
explicit Base(int num1){
this->num1 = num1;
}
virtual ~Base() = default;
};
然后我们可以这样做:
int main()
{
std::vector<std::unique_ptr<Base>> someList;
someList.push_back(std::make_unique<Derived>(100, 1));
someList.push_back(std::make_unique<Derived>(100, 2));
if (auto* dptr = dynamic_cast<Derived*>(someList[0].get()))
std::cout << dptr->num2 << std::endl;
}
对于真实代码,使用Base
中的虚函数而不是使用大量if(dynamic_cast)
检查被认为是更好的设计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.