/*
It is perfectly valid to create pointers that point to classes. We simply have to 
consider that once declared, a class becomes a valid type, so we can use the class 
name as the type for the pointer. For example:

"CRectangle * prect;"

is a pointer to an object of class CRectangle. As it happened with data structures, 
in order to refer directly to a member of an object pointed by a pointer we can
use the arrow operator (->) of indirection. 
*/

#include <iostream>
using namespace std;

class CRectangle 
{
      int width, height;
      public:
             void set_values (int a, int b)
             {
                  width  = a;
                  height = b;
             }
             
             int area () 
             {
                 return (width*height);
             }
};


int main () 
{
    CRectangle rect, *ptr1, *ptr2;
    CRectangle *d = new CRectangle[2];
    
    ptr1 = new CRectangle;

    rect.set_values(1,2);
    
    ptr1->set_values(3,4);
    ptr2 = &rect;
    d->set_values(5,6);
    d[1].set_values(7,8);
    
    cout << "Area of rect: " << rect.area() << endl << endl;
    
    cout << "Area of *ptr1: " << ptr1->area() << endl;
    cout << "Area of *ptr2: " << ptr2->area() << endl << endl;
    
    cout << "Area of d[0]: " << d[0].area() << endl;
    cout << "Area of d[1]: " << d[1].area() << endl;

    delete[] d;
    delete ptr1;
    
    std::cin.get();
    return (0); 
} 
        

/*

Next you have a summary on how can you read some pointer and class operators (*, &, ., ->, [ ]) that appear in
the previous example:
expression can be read as

*x pointed by x
&x address of x
x.y member y of object x
x->y member y of object pointed by x
(*x).y member y of object pointed by x (equivalent to the previous one)
x[0] first object pointed by x
x[1] second object pointed by x
x[n] (n+1)th object pointed by x

*/
