C++ inheritance, base functions still being called when overriden
I have the following two classes, one inherits from the other
Class A{
void print(){cout << "A" << endl;}
}
Class B : A{
void print(){cout << "B" << endl;}
}
Class C : A{
void print(){cout << "C" << endl;}
}
Then in another class I have the following:
vector<A> things;
if (..)
things.push_back(C());
else if (..)
things.push_back(B());
things[0].print();
开发者_如何学编程
this always prints A
I'd like it to print B or C depending on which thing I've added to the vector how do I do this? I've tried abstraction but I'm not entirely sure how to use it in C++ and it hasn't been working for meAs mentioned, you need virtual
functions to enable polymorphic behaviour and can't store classes directly by value in the vector
.
When you use a std::vector<A>
, you are storing by value and thus objects that you add, e.g. via push_back()
are copied to an instance of an A
, which means you lose the derived part of the objects. This problem is known as object slicing.
As already suggested you can avoid that by storing pointers (or smart pointers) to the base class, so only pointers are copied into the vector
:
std::vector<A*> things;
things.push_back(new B());
// ... use things:
things[0]->print();
// clean up later if you don't use smart pointers:
for(std::vector<A*>::iterator it = things.begin(); it != things.end(); ++it)
delete *it;
1) You need to declare print() as virtual in class A.
2) Your vector is incorrect -- you can't store actual class A objects in there; you will need to store pointers to them for the correct behavior (and you will have to clean up after them later) and/or use something like a boost::shared_ptr.
You need to declare the function virtual in your base class, in this case that's class a:
class A{
virtual void print(){cout << "A" << endl;}
}
The other classes will pick this up even if you don't write virtual in those (but you can).
Virtual tells the compiler that the function could be overridden. When you don't use virtual, it's called hiding and works differently, as you've found.
精彩评论