Monday, 16 December 2013

C++ : One-Hour Overview

Hanmant kendre 

(1) User-Defined ADT (Abstract Data Types)
e.g.: "enum" creates a user-defined type.
enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
Months x,y;
    x = FEB; y = DEC;
"struct" creates more flexible user-defined types.
How to define a structure in C and C++.
struct Date {
    int mm;
    int dd;
    int yy;
};
mm, dd and yy are member variables of Date.
struct Complex {
    float real;
    float imag;
};
struct Person {
    long int    ssn;
    char name[40];
    int    age;
    Date dob;
    float salary;
};
A user-defined type can have non-uniform member variables.
How to use a user-defined structure.
Date x, y, *z;        // declaring variables x and y of type Date, and a pointer z to Date type variable.
x.mm = 1;
x.dd = 18;
x.yy = 1998;
// x.mm                    x.dd                         x.yy
1
18
1998
y = x;
cout << y.mm << '/' << y.dd << '/' << y.yy << endl;
z = &x;
cout << z->mm << '/' << z->dd << '/' << z->yy << endl;
Person jeo;
jeo.ssn = 123456789;
strcpy(jeo.name,"Jeo Gates");
jeo.age = 20;
jeo.dob.mm = 7;
jeo.dob.dd = 25;
jeo.dob.yy = 1978;
jeo.salary = 100000.0;
(2) Simple Classes
 
C++ : Classes and Objects.
A class in C++ is a user-defined ADT, just like a struct in C.
An object in C++ is just like a variable in C.
Example:
C (defining a structure and declaring a variable):
struct XY {
    int x;
    int y;
} ;
void main ()
{
    XY v;
    v.x = 0; v.y = 0;
    cout << v.x << v.y;
}
C++: (defining a class and declaring a variable)
class XY {
public:
    int x;
    int y;
};
void main ()
{
    XY v;
    v.x = 0; v.y = 0;
    cout << v.x << v.y;
}
Like structures, classes only define how objects should look like and do not use any memory. Like variables, objects are declared by the programmer and they use memories.
(3) Member Functions
class XY {
public:
    int x; int y;
    void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
          void main ()
       {
            XY v;
            v.x = 0; v.y = 0;
            v.print();
        }
(4) Constructors and Destructors
A constructor is special member function of a class that has the same name as the class.
class XY {
public:
        int x; int y;
        XY( ) {x = 0; y = 0;}
        void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
void main ()
{
    XY v; // constructor is automatically called here.
    v.print(); // no need of v.x = 0; v.y = 0;
}

We can code class definition in xy.h and the main function in main.cpp;
Classes are easy to use and to modify (e.g. adding z).
Note:
(1) A constructor has the same name as the class.
(2) There is no return type or return value.
(3) The compiler provides a default constructor:
        XY( ) { } // do-nothing
        It is better to always provide your own one.
(4) A class can have multiple constructors.
Destructor is another special member function that has the same name as the class preceded with a ~.
(1) Its name consists of the class name preceded by a tilde (~): ~XY ( ) { }
(2) It has no arguments and returns nothing.
(3) The compiler provides a default destructor:
    ~XY( ) { } // do-nothing
    Provide your own destructor if you allocate memories in the object.
(4) A class can have only one constructor.
(5) Overloaded Functions
Overloaded functions: multiple functions have the same name. The compiler decides which one to invoke depending on number of arguments and the types of the arguments.
 
class XY {
public:
    int x; int y;
    XY( ) {x = 0; y = 0;}
    XY(int xin, int yin) {x = xin; y = yin;}
    void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
    XY u; // XY( ) {x = 0; y = 0;} called
    XY v(1,1), w(2,2) ; // XY(int xin, int yin) {x = xin; y = yin;} called
(6) Encapsulation
 
class XY {
private:
    int x; int y;
public:
    XY( ) {x = 0; y = 0;}
    void set(int xin, int yin) { x = xin; y = yin; }
    void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
XY v;
v.x = 1; v.y = 1;     // not allowed, x&y are private.
v.set(1,1);               // ok, set( ) is a public function.
Encapsulation: Private members of a class can only be accessed by its member functions or friend functions.
A class can provide public functions for others to access its private members.
A helper function is a private member function that is only accessible by other member functions.
"protected" members are private but can be accessed by the derived (child) classes.
(7) Inheritance
Orbiters: Planets and Spaceships.
Class Orbiter {
protected:
    int dMass;
    XY xyPosition;
public:
    Orbiter(XY Position, int Mass){ xy Position = Position;  dMass = Mass;}
    XY GetPosition( ) const { return xyPosition; }
    void Fly( ) { xyPosition.x += 10; xyPosition.y += 10;}
    virtual void Display( ) const
        { cout << "The orbiter is at " << "("<< x << "," << y << ")." << endl; }
};
Note:
(1) A "const" function can't modify any data members;
(2) A virtual function can be overridden by the derived classes.
(3) A pure virtual ( = 0) function has to be overridden by the derived classes.
        virtual void Display( ) const = 0;
(4) XY xyPosition declares an imbedded object.
Derived (Child) Classes: inherit all the data members and member functions (except constructors and destructors) of their base (parent) class.
class Planet : public Orbiter {
public:
    Planet(XY xyPosition, int dMass) : Orbiter(xyPosition, dMass)  { /* a do nothing function */ }
    virtual void Display( ) const
        {cout << "The planet is at " << "("<< x << "," << y << ")." << endl; }
};
Planet Earth(ePos,eMass), Jupiter(jPos,jMass);
Note:
(1) Child "class" inherits from parent "class". The parent (base) class has to be defined first. Similar to structure in structure in C.
(2) Each "child" object is an instance of the child class. It has all the member data and functions of both the child class and the parent class.
The Earth or Jupiter Object
dMass
xyPosition
xyThrust
Planet( )
Fly( )
GetPosition( )
Display( )
(3) A "child" object is independent from the object instances of the parent class. Object Earth does not need an Obiter object to exist. It does need the Obiter class to be defined. Inheritance is from a class not from an object.
(4) Orbiter constructor is called first before executing the Planet constructor.
Planet (…) : Orbiter (…) { … }
(5) The default constructor of a child class automatically calls the constructor of the parent class before executing the code in the default constructor. The default destructor does the opposite sequence.
(6)":" inheritance operator, which parent.
    "::" scope resolution operator, which class.
Children can be different.
 
class Spaceship : public Orbiter {
private:
    int dFuel;
public:
    Spaceship (XY xyPosition, int dMass, int Fuel) :
    Orbiter(xyPosition, dMass) { dFuel = Fuel; }
    void Display( ) const
        {cout << "The spaceship is at " << "("<< x << "," << y << ")." << endl; }
    void FireThrusters() { x += 10; y += 10; Fuel -= 1; }
};
(8) Copy Constrctor, Assignment and Other Operators
Copy constructor:
XY(const XY& c) {
    x = c.x;
    y = c.y;
}
    XY a(1,2);
    XY b(a);
? b = a;
Assignment Operators:
const XY& operator= (const XY& e) {
    x = e.x;
    y = e.y;
    return *this;
}
Note:
(1) function name => operator=
    b.operator=(b);
(2) argument => operand
(3) "this" is a pointer generated by the compiler which always points to the current (this) object.
(4) order : object operator operand
(5) returned reference is for chaining.
    XY a(1,1);
    c = b = a;
? XY c = a + b;
        a + b     ==>     a.operator+(b)
        XY XY::operator + (const XY& xy) {
                XY z (x + xy.x, y + xy.y);
                return z;
        }
        XY XY::operator + (const XY& xy) { return XY(x + xy.x, y + xy.y);}
? XY c = a - b;
        XY XY::operator - (const XY& xy) { return XY(x - xy.x, y - xy.y);}
? XY c = a-;
        XY XY::operator - ( ) { return XY(x-, y-);}
? XY c = a * 3;
        XY XY::operator * (const int dMult) { return XY(x * dMult, y * dMult);}
? a *= 3;
        const XY& XY::operator* = (const int dMult) { x *= dMult; y *= dMult;  return *this;}
        Note: a is modified.
? XY c = 3 * a;
Global Operator: not belonging to any class.
        XY operator * (const int dMult, const XY& xy) { return XY(dMult * xy.x, dMult * xy.y);}
        Note:
            (1) Order change : operand operator operand .
            (2) Related member variables need to be public or make the global operator friend.
(9) Stack and Heap Objects
Stack objects: local objects that are not static.
Heap objects: objects allocated on the heap so that their memory remains until being specifically freed.
New & delete: (similar to malloc & free in C)
    XY* pxy;
    pxy = new XY(1,1);
    pxy->display();
    delete pxy;
    pxy = new XY[64]; // cannot specify initializer for arrays
    pxy[0].display();
    delete [] pxy;
    Note:
         (1) Array deletion needs [], different from free.
         (2) delete has to go with new, free has to go with malloc.
(10) Friend Classes and Friend Functions
A friend is nonmember of a class that is given access to the nonpublic members of a class.
Friend Classes
    class YX {
    friend class XY;
    private:
        int y; int x;
    public:
        YX() {y = x = 0; }
    };
class XY {
    public:
        int x; int y;
        void copyYX(const YX& yx) { x = yx.x; y = yx.y; }
        void writeYX(YX& yx) { yx.x = x; yx.y = y; }
    };
    XY xy; YX yx;
    xy.copyYX(yx);
    Note:
        (1) All member functions of XY are allowed to access any data of YX,
                because YX has declared XY as a friend.
        (2) Friendship can be declared to individual functions.
Friend Functions:
    class YX {
        friend void XY::copyYX(const YX& yx);
        friend void XY::writeYX(YX& yx);
        friend int tan(const YX& yx); // global
        …
     };
    int tan(const YX& yx) { return yx.x / yx.y; }
(11) Polymorphism
Polymorphism is the ability to call a variety of functions using exactly the same interface.
    Obiter o(1,1); Planet p(2,2); Spaceship s(3,3);
    Obiter *a[3];
    a[0] = (Obiter *) &o;
    a[1] = (Obiter *) &p;
    a[2] = (Obiter *) &s;
    for(i=0; i<=2; i++) a[i]->Display();
    /* => o.Display(); p.Display(); s.Display(); */
    The orbitor is at (1,1).
    The planet is at (2,2).
    The spaceship is at (3,3).
Comparison of polymorphic and overloaded functions:
    (1) A set of polymorphic functions have exactly the same name, same number of parameters of the same types. A set of overloaded functions have the same name but with different number or different type of parameters.
    (2) A set of polymorphic functions belong to different classes of a class hierarchy. The function in the base class has to be virtual. A set of overloaded functions belong to the same class.
    (3) Polymorphic functions are differentiated by the (creation) classes of the objects. Overloaded functions are differentiated by their arguments (number and type).
(12) Templets: Parameterized class definition.
    Regular class definition: class Name { ... };
    Regular object declaration: Name obj;
    Templet definition: template <class Type>
    class Name {Type ... }
    Templet object declaration: Name<Type> obj;
    Example: any-type array class:
        template <class Type>
            class Array {
            public:
                Type *ap;
                 int size;
                Array(int sz) {size = sz; ap = new Type [size]; }
                ~Array() {delete [] ap;}
                Type& operator[] (int index) { return ap[index]; }
            };
        Array<int> ia(4);
        Array<char> ca(5);
        Array<double> da(6);
        e.g. Type is int.
        Array<int> ia(4);
            class Array {
                public:
                    int *ap;
                    int size;
                    Array(int sz) {size = sz; ap = new int [size]; }
                    ~Array() {delete [] ap;}
                    int& operator[] (int index) { return ap[index]; }
            };
(13) Static Class Members
Static data members are global to the whole class rather than local to any specific object.
    class XY {
        public:
            static int s_nCount;
            int nCount;
            XY() : nCount(0) { s_nCount++; nCount++;}
            void Display() { cout << s_nCount << "," << nCount << endl; }
            static int& GetCounter() { return s_nCount; }
    };
    int XY::s_nCount = 0;
    void main()
    {
    XY u; // u.s_nCount == 1 and u.nCount == 1
    XY v; // v.s_nCount == 2 and v.nCount == 1
    XY w; // w.s_nCount == 3 and w.nCount == 1
    u.Display(); // 3,1
    v.Display(); // 3,1
    w.Display(); // 3,1
    }
Static Member Functions are for accessing static member data.
    void main()
    {
    XY::GetCounter()++;
    XY u, v, w;
    XY::GetCounter()++;
    u.s_nCount++;
    v.s_nCount++;
    w.s_nCount++;
    u.Display(); // 8,1
    }
Note:
    (1) A static function can be used without declaring an object.
    (2) It does not contain a "this" pointer.
    (3) It cannot reference any non-static member (data or function).
    (4) Non-static functions can access static members.
(14) Separating Class Definitions from Code
      XY.h contains XY class definition.
    XY.cpp contains XY member functions.
    Class users need only check on XY.h for information.
    Class authors write the functions in .cpp
(15) References
 
C++: How to Program, Deitel & Deitel, Prentice Hall.
Program Development and Design Using C++, Cary J. Bronson, PWS.
Beginner's Guide to C++ by Oleg Yaroshenko, WROX.
C++ Primer by Stanley Lippman, Addition-Wesley.
The Annotated C++ Reference Manual (ANSI Base Document) by Margret Ellis and         Bjarne Stroustrup, Addition-Wesley.

No comments:

Post a Comment