7

Consider the following code:

class A { public: virtual ~A() { } virtual void print() const { std::cout << "In A" << std::endl; } }; class B : public A { public: B() { } virtual ~B() { } virtual void print() const { std::cout << "In B" << std::endl; } }; void doSomething(A* a) { a->print(); } void doSomething(const A a) { a.print(); } int main() { A* a = new B(); doSomething(a); doSomething(B()); return 0; } 

Why does this output:

In B In A 

But when you change doSomething to doSomething(const A& a) it outputs:

In B In B 
0

1 Answer 1

12

This is known as slicing.

When passing A by value, a local copy is made, by copying just the A part of the caller's object. Since this has both a static and dynamic type of A, that's the override of print that's chosen.

Passing by reference, the function gets a reference to the caller's object with dynamic type B, so that override is chosen.

Using abstract base classes can prevent confusing behaviour like this - they can't be directly instantiated, and so can't be passed by value.

Sign up to request clarification or add additional context in comments.

Comments