user1508519
user1508519

Reputation:

Passing derived class by reference to function taking base class as parameter

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

Upvotes: 7

Views: 6522

Answers (1)

Mike Seymour
Mike Seymour

Reputation: 254431

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.

Upvotes: 12

Related Questions