Here is the solution for HW2:
2.1 - Information hiding: Making users inaccessible to the parts of the object
      nor its implementations.
    - Encapsulation: Grouping of data and the operations that apply to them
      to form an aggregate, while hidding the implementations.
      C++ supports these with "class" mechanism.

2.2 - Private section is  inaccessible to the users. It can be accessed only
      by the member functions in the public section.
    - Public section is the interface of the class, visible to the users of 
      the object.

2.3 - Constructor initializes class's members, whenever an object of this
      class is instantiated.
    - Destructor is called when an object is destroyed, that is, when 
      program execution leaves the scope in which an object of that class was
      instantiated. Destructor performs the clean-up task before the system
      reclaims the object's memory space so that it may be used to hold new
      objects.

2.4 - Copy constructor creates a new object initialized to a copy of the 
      same type of ofject.
    - Copy assignment operator performs a copy into an existing object.

2.5 - Compiler provides the default constructors and destructor. Default
      constructor initializes each data member using the data member's 
      construction method. If those methods are not defined, no initialization
      is performed.
    - Default destructor calls the destructor of each data member if available.
      Otherwise, those members are popped up from the stack. Therefore, 
      memory leak could happen.

2.6 - It is acceptable not to provide a destructor if there is no dynamic 
      memory allocation.
    - It is acceptable not to provide copy constructor and operator=, if
      shallow coping is OK for this class. 

2.7 - Using inline can save you the overhead cost of function call. However, 
      big inline functions can cause the code bloat problem. 

2.8 - The following operators can't be overloaded: ., .*, ?:, sizeof.
    - Precedence can't be changed.
    - Only existing operators can be overloaded.
    - You cann't create new operators.

2.9 - Functions that are exempt from private restriction.

2.10 - friend ostream& operator<< (ostream& os, const ClassName&);
       friend istream& operator>> (istream& is, const ClassName&);
     - The definition could be place in either header file or implementation
       file
2.11 - a) The 1st constructor is called. Default values used for Numer and 
          Denom.
       b) The 1st constructor is called. Numer = 3, Denom = 1.
       c) The 2nd constructor is called. Numer = 4, Denom = 4.
       d) The 1st constructor is called. Numer = 0, Denom = 1.
       e) Illegal.
       f) Illegal, if there is no function named F, returning an object
          of type Rational and taking no argument, defined.
       g) The 2nd constructor is called, 'new' returns a pointer to memory 
          in heap that contains a Rational object with Numer = 4, Denom = 3.
       h) The 1st consturctor is called, same as g) 'new' returns a pointer
          to the Rational object in heap with Numer = 5, Denom = 3.
       i) the 1st constructor is called 5 times. 5-element array is created
          on the heap.

2.12  - delete G;
        delete H;
        delete [] I;

2.13  - Because this class will not be accessible by the users.

2.14  - The operator returns the number of bytes required to store an object 
        of this class. The number results from adding up the storage required
        for each (private and public)data member.