// temp0.cpp #include class Y { public: virtual ~Y() { std::cout << "\n ~Y() called"; } Y() { std::cout << "\n Y() called"; } Y(const Y& y) { std::cout << "\n Y(const Y&) called"; } virtual void say() const { std::cout << "\n y here"; } virtual void doWork() { /* no work done here */ } }; class X : public Y { public: X() : val(0) { std::cout << "\n X() called"; } X(const X& x) : val(x.val) { std::cout << "\n X(const X&) called"; } virtual void say() const { std::cout << "\n x here, my value is " << val; Y::say(); } void doWork() { ++val; } private: int val; }; void myFun1(Y y) { std::cout << "\n-- myFun1(Y y) --"; y.doWork(); y.say(); std::cout << "\n-----------------"; } void myFun2(Y& y) { std::cout << "\n-- myFun1(Y& y) --"; y.doWork(); y.say(); std::cout << "\n-----------------"; } void myFun3(const Y& y) { std::cout << "\n-- myFun3(const Y& y) --"; // y.doWork(); won't compile because doWork is not const y.say(); std::cout << "\n-----------------"; } void main() { myFun1(X()); // sliced to a Y, uses Y::say(), Y::doWork() std::cout << "\n"; myFun2(X()); // base reference uses X::say(), X::doWork() polymorphically std::cout << "\n"; myFun3(X()); // base reference uses X::say(). Can't use non-const X::doWork() std::cout << "\n\n"; }