c++中的多态性,父类向量中的类型丢失
我有一个 A 类,它是 B 类和 C 类的父类.还有一个类 X,它是 Y 和 Z 的父类.
I have a class A, which is parent to classes B and C. And a class X, which is a parent to Y and Z.
class A {};
class B : public A {};
class C : public A {};
class X
{
void foo(A) { std:: cout << "A"; }
};
class Y : public X
{
void foo(B) {std::cout << "B"; }
};
class Z : public X
{
void foo(c) {std<<cout <<"C"; }
};
int main()
{
B b;
C c;
Y y;
Z z;
y.foo(b);//prints B // b is a B, and Y::foo takes a B, hence print B
y.foo(c);//prints A // mismatch between types, fall back and print A
z.foo(b);//prints A // mismatch between types, fall back and print A
z.foo(c);//prints C // c is a C, and Y::foo takes a C, hence print C
std::vector<A> v;
v.push_back(b);
v.push_back(c);
//In this loop, it always prints A, but *this is what I want to change*
for (size_t i = 0; i < v.size(); ++i)
{
z.foo(v.at(i));
y.foo(v.at(i));
}
}
是否可以让项目打印与硬编码调用相同的结果?这意味着我会将它们视为原始类型,而不是其父类型?或者一旦我将它们放入 A 的向量中,它们将永远属于 A 类型?
Is it possible to get the items to print the same result as the hard coded calls? Meaning that I will treat them as their original type, and not its parent type? or once I put them int a vector of A they will forever be of type A?
推荐答案
你看到的是 对象切片.
您将派生类的对象存储在一个向量中,该向量应该存储基类的对象,这会导致对象切片,并且正在存储的对象的派生类特定成员被切掉,因此存储在向量中的对象只是充当基类的对象.
What you are seeing is Object Slicing.
You are storing object of Derived class in an vector which is supposed to store objects of Base class, this leads to Object slicing and the derived class specific members of the object being stored get sliced off, thus the object stored in the vector just acts as object of Base class.
解决方案:
你应该在向量中存储指向基类对象的指针:
You should store pointer to object of Base class in the vector:
vector<X*>
通过存储指向 Base 类的指针,就不会进行切片,您还可以通过使函数 virtual
来实现所需的多态行为.
正确的做法是使用合适的智能指针 而不是在向量中存储原始指针.这将确保您不必手动管理内存,RAII 会自动为您完成.
By storing a pointer to Base class there would be no slicing and you can achieve the desired polymorphic behavior as well by making the functions virtual
.
The right approach is to use a suitable Smart pointer instead of storing a raw pointer in the vector. That will ensure you do not have to manually manage the memory, RAII will do that for you automatically.
相关文章