保存在基本 class 类型向量中的基本和派生对象被切片

Base and derived objects held in vector of base class type get sliced

所以我刚刚学习了矢量模板的基础知识,我正在尝试制作一个同时包含 Base 对象和 Derived 类对象的矢量。但是派生对象被切片(只打印 baseVariable 虽然它也应该打印 DerivedVariable。所以我有两个问题,首先: 是否在此处正确创建了用户输入的新对象?我可以让它变得更好或更短吗?

Base* ptr = new Base();
            cin >> *ptr;
            vec.push_back(unique_ptr<Base>(ptr));

为什么 Derived 对象会被切片?

class Base
{
protected:
    string baseVariable_;
public:
    void display() {
        cout << "BaseVar: " << baseVariable_ << endl;
    }
    friend istream& operator>>(istream& in, Base& obj);

};
istream& operator>>(istream& in, Base& obj)
{
    in >> obj.baseVariable_;
    return in;
}



class Derived :public Base
{
public: //public just for test
    string derivedVariable_;
    void display() {
        Base::display();
        cout << "DerivedVar: " << derivedVariable_ << endl;
    }
    friend istream& operator>>(istream& in, Derived& obj);
};
istream& operator>>(istream& in, Derived& obj)
{
    in >> obj.baseVariable_>> obj.derivedVariable_;
    return in;
}
int main()
{
    unsigned int choice = 0;
    vector<unique_ptr<Base>>vec;
    while (true)
    {
        cout << endl << "1. Add object of base class" << endl;
        cout << endl << "2. Add object of derived class" << endl;
        cout << endl << "3. Display all added objects to vector";
        cout << endl << "Choose option: ";
        cin >> choice;
        switch (choice)
        {
        case 1:
        {
            Base* ptr = new Base();
            cin >> *ptr;
            vec.push_back(unique_ptr<Base>(ptr));
            
            break;
        }
        case 2:
        {
            Derived* ptr = new Derived();
            cin >> *ptr;
            vec.push_back(unique_ptr<Base>(ptr));
            //delete ptr; <- it can't be here.
            break;
        }
        case 3:
            cout << "Displaying...\n";
            for (size_t i = 0; i < vec.size(); i++)
            {
                vec[i]->display();
            }
            cout << "---------------------\n";
            break;

        }
    }
}

您的代码中没有切片。您忘记将 Base::display 声明为虚拟的,因此在 Base* 上调用 display 将调用 Base::display.

class Base
{
protected:
    string baseVariable_;
public:
    virtual void display() {
    // ^^----------------------------------------------- !!!
        cout << "BaseVar: " << baseVariable_ << endl;
    }
    friend istream& operator>>(istream& in, Base& obj);
    virtual ~Base() {}
};

对于多态类型,您还需要添加一个虚拟析构函数。