I'm fairly new to c , and I'm trying to understand as much as possible of the language and the underlying mechanics.
I am confused about a specific case where I can't seem to access the correct member function when I have two classes (Base and Derived) even though I define them as virtual.
class Base {
public:
virtual void print() { std::cout << "Base" << std::endl; };
};
class Derived : public Base {
public:
virtual void print() { std::cout << "Derived" << std::endl; };
};
int main() {
Base b;
Derived d;
b.print();
d.print();
Base* p1 = &b;
Base* p2 = &d;
p1->print();
p2->print();
std::vector<Base> v { b, d };
v[0].print();
v[1].print(); // Why doesn't this print "Derived?"
return 0;
}
Output:
Base
Derived
Base
Derived
Base
Base <- ??
virtual
seems to "work" with pointers of type Base
, but not for objects in vector<Base>
.
What's going on?
CodePudding user response:
Because of object slicing. When you create your vector you copy your objects into it.
std::vector<Base> v{ b, d };
The catch is that inside the std::vector
you have only objects of type Base
, NOT Base
and Derived
. If you want polymorphic behavior with containers in C , you usually do it with pointers, as you can't keep raw references in them.
std::vector<Base*> v{ &b, &d };
for (Base* ptr : v) {
ptr->print();
}