保存在基本 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() {}
};
对于多态类型,您还需要添加一个虚拟析构函数。
所以我刚刚学习了矢量模板的基础知识,我正在尝试制作一个同时包含 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() {}
};
对于多态类型,您还需要添加一个虚拟析构函数。