#include<iostream>

using namespace std;

class X {
protected:
   int i;
public:
   X() : i(10) {}

   void set(int ii)
   {  cout << "This is X::set" << endl;
      i = ii; }

   int get() const
   {  return i; }

   int double_val()
   {  cout << "Printing from X::double_val: " << i << endl;
      return i = i * 2; }
};

class Y : public X {
   int i;

public:
   Y() : i(0) {}

   int change()         // new function
   {  i = double_val(); // inherited function
      return i; }

   void set(int ii)     // redefined function
   {  i = ii;
      X::set(ii);       // inherited function
      cout << "This is Y::set" << endl;  }

   void print() const
   {
//    X x;
//    cout << x.X::i << endl;   // CAREFUL: This is not allowed:
                                // x is superclass object
      cout << "X::i " << X::i << endl;
//    cout << "X::i " << X::get() << endl;
//    cout << "X::i " << get() << endl;
      cout << "Y::i " << i << endl; }
};

int main()
{
/* //// BLOCK A ////
   cout << "sizeof(X) = " << sizeof(X) << endl;
   cout << "sizeof(Y) = " << sizeof(Y) << endl;
*/

   Y obj;

/* //// BLOCK B ////
   obj.change();
   obj.print();
*/

/* //// BLOCK C ////
   obj.double_val();
   obj.print();
*/

/* //// BLOCK D ////
   obj.set(120);
   obj.print();
   obj.X::set(12);
   obj.print();
*/
   return 0;
}
