微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决保存在基类类型向量中的基类和派生对象被切片

所以我刚刚学习了矢量模板的基础知识,我正在尝试制作一个包含 Base 的对象和派生类的对象的矢量。但是派生对象被切片(只打印 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 声明为虚拟的,因此在 display 上调用 Base* 将调用 Base::display

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。