繁体   English   中英

无法避免 object 在 c++ 中切片

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM