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()
?
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();