This example was taken from Bruce Eckel "Thinking in C ++." Chapter 14, “Acceleration and Copy Builder” section.
#include <iostream> using namespace std; class Parent { int i; public: Parent(int ii) : i(ii) { cout << "Parent(int ii)\n"; } Parent(const Parent& b) : i(bi) { cout << "Parent(const Parent&)\n"; } Parent() : i(0) { cout << "Parent()\n"; } friend ostream& operator<<(ostream& os, const Parent& b) { return os << "Parent: " << bi << endl; } }; class Member { int i; public: Member(int ii) : i(ii) { cout << "Member(int ii)\n"; } Member(const Member& m) : i(mi) { cout << "Member(const Member&)\n"; } friend ostream& operator<<(ostream& os, const Member& m) { return os << "Member: " << mi << endl; } }; class Child : public Parent { int i; Member m; public: Child(int ii) : Parent(ii), i(ii), m(ii) { cout << "Child(int ii)\n"; } friend ostream& operator<<(ostream& os, const Child& c) { return os << (Parent&)c << cm << "Child: " << ci << endl; } }; int main() { Child c(2); cout << "calling copy-constructor: " << endl; Child c2 = c; cout << "values in c2:\n" << c2; }
The author makes the following comment regarding this code:
"The <<operator for the Child is interesting in that it calls the <operator for the parent part inside it: by casting the Child object for the parent & (if instead you drop the object of the base class of the link, you usually get unwanted results):
return os << (Parent&)c << cm << "Child: " << ci << endl;
I also run the program, replacing the above statement with:
return os << (Parent)c << cm << "Child: " << ci << endl;
and the program works without problems, with only one expected difference. Now the Parent copy constructor is called again to copy the argument c to Parent::operator<<() .
What then are the undesirable results that the author speaks of?
source share