Home > Back-end >  Dynamic binding and virtual functions - Vector of base class objects, access the "correct"
Dynamic binding and virtual functions - Vector of base class objects, access the "correct"

Time:10-27

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();
}
  • Related