Question

Given the base and derived classes as below:

The base:

class AA
{
public:
    AA() = default;
    virtual void print() const { std::cout << aa << "\n";}

private:
    std::string aa = "AA";
};

The derived:

class BB : public AA
{
public:
    BB() = default;
    virtual void print() const override {std::cout << bb << "\n"; }

private:
    std::string bb = "BB";
};

The first try:

int main()
{
    AA aa;  BB bb;
    AA& //r = aa; r.print();

    r = bb;
    r.print();

    return 0;
}

The outcome was exactly what I had expected:

BB
Press <RETURN> to close this window...

But the second try when // was removed:

int main()
{
    AA aa;  BB bb;
    AA& r = aa; r.print();

    r = bb;
    r.print();
 //!^^^^^^^^^^--why wasn't the print in derived class called?
    return 0;
}

The output was:

AA
AA
Press <RETURN> to close this window...

As commented above, why wasn't the print defined in the derived class called when executing the second r.print()?

Was it helpful?

Solution

Because the expression r = bb is exactly equivalent to aa = bb. The assignment operator merely copies the parts of bb known to the AA class into the aa object.

In other words, after the assignment, r still points to aa, which is an instance of AA. It does not point to a BB instance in any sense.

A reference can never change which object it refers to, so the expected behavior cannot be achieved with references. To get the polymorphism you're looking for, you muse use pointers:

AA* p = &aa;
p->print();

p = &bb;
p->print();

OTHER TIPS

Because of this:

r = bb;

The above statement does not bind (rebind?) the reference r to bb. Instead, it copies the AA parts of bb into aa which is the object referred to by r.

To test the above claim, here is an example: http://coliru.stacked-crooked.com/a/00d20990fe0ddd26

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top