0

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?

2
  • 1
    You can't create vectors of baseclass objects. This is like assigning a derived object to a base object and causes "slicing" or "truncation". This is a well-known issue. Commented Oct 27, 2021 at 7:24
  • 2
    Does this answer your question? What is object slicing? Commented Oct 27, 2021 at 7:25

1 Answer 1

1

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();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.