C++ Can';t避免在c+中进行对象切片+;

C++ Can';t避免在c+中进行对象切片+;,c++,polymorphism,stdvector,object-slicing,C++,Polymorphism,Stdvector,Object Slicing,我想构造一个std::vector,其中包含从Base类派生的对象。我知道我不能直接将整个对象推入向量(对象切片的原因),所以我使用智能指针。然而,它仍然不起作用。我做错了什么 我的代码: struct Base{ int num1; explicit Base(int num1){ this->num1 = num1; } }; struct Derived : Base{ int num2; explicit Derived(

我想构造一个
std::vector
,其中包含从
Base
类派生的对象。我知道我不能直接将整个对象推入
向量(对象切片的原因),所以我使用智能指针。然而,它仍然不起作用。我做错了什么

我的代码:


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 !
}


结构基{
int num1;
显式基(int num1){
这->num1=num1;
}
};
派生结构:基{
int num2;
显式派生(intnum1,intnum2):基(num1){
这->num2=num2;
}
};
int main()
{
向量someList;
someList.push_back(std::make_unique(100,1));
someList.push_back(std::make_unique(100,2));

std::coutnum2派生的
对象及其
num2
成员都在那里,但是类型系统不知道这一点(在类似的代码中,可能不确定)

someList[0]
的类型是
std::unique\u ptr
,因此
->
操作符允许命名
Base
的成员。一般来说,
unique\u ptr
可能根本不指向
派生的
,因此这是安全的方法

如果
Base
类型是多态的,您可以使用
dynamic\u cast
来检查对象是否确实是
派生的
。要使此工作正常,让我们向
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;
}
intmain()
{
向量someList;
someList.push_back(std::make_unique(100,1));
someList.push_back(std::make_unique(100,2));
if(auto*dptr=dynamic_cast(someList[0].get())

std::coutnum2派生的
对象及其
num2
成员都在那里,但是类型系统不知道这一点(在类似的代码中,可能不确定)

someList[0]
的类型是
std::unique\u ptr
,因此
->
操作符允许命名
Base
的成员。一般来说,
unique\u ptr
可能根本不指向
派生的
,因此这是安全的方法

如果
Base
类型是多态的,您可以使用
dynamic\u cast
来检查对象是否确实是
派生的
。要使此工作正常,让我们向
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;
}
intmain()
{
向量someList;
someList.push_back(std::make_unique(100,1));
someList.push_back(std::make_unique(100,2));
if(auto*dptr=dynamic_cast(someList[0].get())

std::cout num2
std::unique\u ptr::operator->()
允许您仅访问
Base
的成员,因为返回类型是
Base*
;您需要执行强制转换才能实际访问
派生的
的成员。由于您仅访问
派生的
的成员,向量模板参数的选择似乎有问题。也许您可以包括一些关于至少,您正试图在程序中执行。(这实际上可能是一个XY问题)您需要一个在
Base
中定义并在
Derived
中重写的虚拟函数。感谢您的提示,我正在尝试使用从
Base
派生的元素填充
std::vector
,例如,让我们调用基类
Dog
,然后我可能有一个向量,其中包含
Beagle
对象或
BorderCo>llie
对象,但我只知道我在运行时是否在处理Border Collies的小猎犬。什么样的虚拟函数?@n.“代词是m。我对c++非常陌生。我建议在尝试使用继承之前,先阅读虚拟函数和一般的面向对象编程。这不是一个小主题和注释部分不适合解释它。
std::unique\u ptr::operator->()
允许您仅访问
Base
的成员,因为返回类型是
Base*
;您需要执行强制转换才能实际访问
派生的
的成员。由于您仅访问
派生的
的成员,向量模板参数的选择似乎有问题。也许您可以包括一些关于至少,您正试图在程序中执行。(这实际上可能是一个XY问题)您需要一个在
Base
中定义并在
Derived
中重写的虚拟函数。感谢您的提示,我正在尝试使用从
Base
派生的元素填充
std::vector
,例如,让我们调用基类
Dog
,然后我可能有一个向量,其中包含
Beagle
对象或
BorderCo>llie
对象,但我只知道我在运行时是否在处理Border Collies的小猎犬。什么样的虚拟函数?@n.“代词是m。我对c++非常陌生。我建议在尝试使用继承之前,先阅读虚拟函数和一般的面向对象编程。这不是一个小主题和注释部分不适合解释它。谢谢!在这个例子中,我将如何“在Base中使用虚拟函数”要获得相同的行为?@CharStyleаааааазаааааааааазаааа在
Base
中添加一个
virtual code>方法,该方法返回
int
,然后让
派生的
重写该方法e我如何“利用Base中的虚拟函数”要获得相同的行为?@CharStyleаааааазаааааааааазаааааааазааа。