Object Oriented Programming (OOP) in C++… short descriptions of all you need to know.

This post is highly inspired by and can be considered as some of my class notes for the Software Engineering course (CS20006) at IIT Kharagpur taught by Prof. Partha Pratim Das.

Many of the code illustrations are snapshots of the output along with the code using the application Xcode for Mac OS X. These should be followed thoroughly as these cover extra informations.


Procedural Enhancements over C: 


HOW STUFF WORKED IN C – THE SYNTAX

Image

THE CONST Keyword

Image

THE ENTRY OF REFERENCES

Image

Call by reference (act as in-out parameters),

whereas call by value acts as strictly-in parameters.

Image

Return by reference 

not to be used with local variables inside function (return value is now not copied back!)

Image

Pointers vs. References

  • Pointers can point to NULL whereas References cannot. There is nothing defined as NULL Reference.
  • Pointers can point to different variables at different times whereas for a reference, its referent is fixed.
  • References make code faster since, unlike pointers, checks for NULL are not required.
  • Reference “refers” to an address but does not store that address. Pointer does.
  • Can not have an array of references, not allowed.
  • You should never return by reference a local variable

MACROS and Inline Functions:

  • C Pre-Processor (CPP) macros are replaced textually before compilation, in turn:
    • Size increases
    • Speed increases
    • Perfect for small code reuse
    • Some expressions might turn out to be unexpected and in some cases compiler dependent.
    • Scope of the variables confined to where it’s being implemented (Can be both useful and harmful)
  • Inline Functions
    • Act as functions, implemented as macros
    • Type Checking is still performed.
    • May take more space
    • Implemented by using inline keyword
    • are to be defined in .h files not .c/.cxx files preferably..
    • Inline Functions are not always implemented inline, this is decided by the compiler based on the performance. See here for good answers.

Default Function Arguments: 

(Preferably in header files to avoid contradictions)

Image

Function Overloading:

  • Same function name can be used by different kind of definitions.
  • Function selection based on number and types of the actual parameters at the places of invocation.
  • Function selection (Overload Resolution) is performed by the compiler in the following order:
    • Exact Match
    • Promotion
    • Standard Type Conversion (like function-to-pointer and array-to-pointer)
    • User Defined Type Conversion
  • Two functions having the same signature but different return types will result in a compilation error due to “attempt to re- declare”.
  • Allows static polymorphism …

New-Delete Operators:

  • new Operator when called can be considered as performing these two operations:
    • Allocates memory in Free Store
    • Calls the constructor (discussed later)
  • delete Operator when called can be considered as performing these two operations:
    • Calls the Destructor
    • Frees up the memory in Free Store

Image


Classes in C++:


What is a Class?:

  • C++ Class is an implementation of “type”
  • In C++, class is the only way to implement user defined data types.
  • An object (any variable of that type, also called an instance) is an aggregate(encapsulation) of data items(member variables) and methods(member functions) that can work with them.
  • A Class is a layout of it’s objects.

How to code them?

  • A Class is defined by “class” keyword.
  • Each member in a class has an access specifier.
    • public: These members are accessible everywhere.
    • private: These members are accessible inside the definition of the class
    • protected: These are accessible only to it’s class definition and it’s subclass definitions.

“this” pointer: 

  • follows the type – X * const , where X is the class name as the pointer address can not be changed.
  • Necessity of this to the programmer:
    • Distinguishing data member from non-member variable
    • Explicit Use
  • Member functions implicitly take this pointer as an argument.

Constructor Functions:

  • are member functions with the same name as the class
  • are automatically called when an object is created, just after memory allocation.
  • allow the class to initialise the state of an object
  • Constructors also allocate additional memory space from the Free store (if) required for the object.
  • must not have any return type , not even void.
  • If users do not define any constructor then the compiler provides a default constructor.
  • Default constructors are those constructors which either do not have an argument or have default arguments (ints to 0, pointers to NULL) for all parameters.  can be directly called to create anonymous objects.
  • can be overloaded.
  • X a; invalid if no default constructor (if user defined constructor is not a default kind)
  • Initializer Lists: 
    • Initializer lists appear as a comma separated list
    • Initializer lists are required for a member object that must be passed initial arguments for construction
    • Initializer lists are required for const members and reference members
  • local static specifier:
    • created first time you cross them
    • destructed in terms of global variables
    • However, scope is lexically restricted, as usual, by braces.

Destructor Functions:

  • are member functions with the name “~<class-name>
  • is automatically called when an object is destroyed, just before memory is freed.
    • For auto variables when the variable goes out of scope
    • For objects created in the Free store, destructor is called after “delete” or “delete[]” is explicitly invoked by the programmer.
  • must not have any argument
  • must not have any return value
  • If destructor is not called then there could be memory leaks for objects which calls “new” in the constructor.
  • Also a free function (provided by default if needed)
  • Provides an Automatic Life Time 
  • If destructor is private, or not provided by any other way… then creation of an object is a compile error. 

Copy Constructor Functions:

  • Copy constructor is a special constructor which is used to initialize an object with another object of the same type.
  • Functions call it for both arguments and return.
  • Needs to take a reference as its argument because if not taken as reference, an infinite loop occurs as C++ itself calls the copy constructor for argument values.

Ahh! That’s a lot, let’s see all of them working!

Image

Object Layout w.r.t. memory:

  • Simplistically, an object of a class must have enough space to store all members of that class.
  • No space is required per object for storing function pointers for the methods declared in the class.
  • Class members can also be objects.
  • All objects get allocated a contiguous chunk of memory
  • Arrays of Objects:
    • String arrayOfString[100]; // 100 objects created using the default constructor
    • String arrayOfString[2] = { String(“abc”), String(“def”) }; // Using specialized constructor while creating an array of objects.
    • String *pArrayOfString[2] = { new String(“abc”), new String(“def”) };//Using different constructor for creating array objects dynamically.

Const Member Functions:

  • Constant Member Functions are not allowed to change the state of the object on which they are invoked.
  • Type of this pointer passed to a const function is thence const X* const this
  • Const Functions are declared with keyword const following member function parameter list.
  • const must also be present at the definition.
  • for escaping const member functions’ const-ness you can use mutable keyword

Image

Friends and Static Data:

  • Friend Functions 
    • are to be declared in one or more classes
    • behave like global functions and can’t be called on an object(no this pointer), they behave like global functions.
    • have access to the private members of those classes
    • are distinguished from members with the keyword friend
    • Member of a different class may be a friend function. (e.g. friend Vector Vector::prod(Matrix *pM);)
    • A class may be declared as a friend implying all member functions of that class are friends.
    • Friend-ship is neither commutative nor transitive.
    • It is best to avoid friend in an ideal OO Design.
    • Can be used for operators in which both ways needed  (like  int+Fraction, and Fraction+int)
  • Static Data Members 
    • A static data member is shared by all the objects of a class.
    • Static data member may be public or private.
    • Static data member must be initialized in a source file.
    • It can be accessed
      • with the class-name followed by the scope resolution operator “::”
      • as a member of any object of the class
    • Static Member functions:
      • May be invoked with the class-name::
      • May be invoked  as part of any objects interface
      • this pointer is not passed to a static function
      • must not refer to non-static members of its “invoking object”  
    • Features like Singleton Class (only one instance possible) can be implemented using static variables. {Make constructor private and store a static instance pointer, which will be returned by some method getInst() only if instance is not there

Operator Overloading:


Points to remember:

  • An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations.
  • can be postfix or infix for unary
  • “a+b” calls either a.operator+(b) or operator+(a,b)
  • These functions can either be implemented as global friend functions and/or methods.
  • Overloaded operator function must exist… i.e. you can only overload.
  • Overloaded operator function must not change the arity of already present operator
  • precedence and associativity should not change
  • Fraction& operator–(); for infix… no argument for unary operator
  • Fraction operator–(int); for postfix
  • Some operators can’t be overloaded, e.g. ::,.*.?:,., sizeof() etc.
  • Conditional Operators like &&, ||, comma operator should not be overloaded.
  • Member operators will not help if the left hand side of the operator is not of the class type…. for this reason stream operators must be friend
  • Returning const from a function ensures that you can’t use operations like (a*b)=c
  • Returning const ensures that overloaded “*” is compatible with the same operator on built-in types.

Assignment Operator:

  • Poly& operator=(const Poly&);
  • Poly returned because it makes chain assignment possible
  • Some cases in which you need to free some data before copying new data, make sure that self assignment can also take place
  • Reference returned to allow (a=b)=c, kind of statements… also some operators are left associative, in that case return must be by reference… e.g. (next point)
  • System defined assignment operator function makes a shallow copy.
  • If there is a need to define a copy constructor then there must be a need to overload assignment operator and vice-versa.

Inheritance


Image

What is inheritance: We say that a class(also called the subclass or derived class) inherits another class( also called the super class or base class) if the sub class has all the data attributes of the super class. C++ provides a special syntax with which use this special relation. When we use inheritance , all data members and methods of the base class are immediately available to the derived class. The derived class, however, may extend the state and behavior of the base class by adding more attributes and methods.

Advantages:

  • Reusability, reuses an already existing code
    • Reduces cost & development time.
    • Improves quality.
    • In C, we had to reuse a code using a library function… which can not be customised
    • In C++, we have features like inheritance and composition(code reuse by containing other classes
  • Extensibility
  • Data hiding, base class can decide to keep some data private so that it cannot be altered by the derived class
  • Overriding

Behaviour of Access Specifiers for members:

  • public: public for derived classes.
  • private: private for derived classes, can not be used by derived class members.
  • protected: private for derived classes, but can be used by them.

Accessibility based on type of inheritance:

  • public: Mostly needed… and mostly used.
    • private members of the base class become private members of the derived class, but can not be accessed by the derived class members!
    • However, the private members of the base class will still be accessible by the methods inherited from the base class.
    • public members of the base class become public members of the derived class
  • private: All members of base class behave as private to the derived.
  • protected: public and protected members become protected, and private members stay private.
Public inheritance
Base access specifier Derived access specifier Derived class access? Public access?
Public Public Yes Yes
Private Private No No
Protected Protected Yes No
Private inheritance
Base access specifier Derived access specifier Derived class access? Public access?
Public Private Yes No
Private Private No No
Protected Private Yes No
Protected inheritance
Base access specifier Derived access specifier Derived class access? Public access?
Public Protected Yes No
Private Private No No
Protected Protected Yes No

Order of Constructor/Destructor Calls:

  • Constructor
    • Base then Derived, as derived object members contain members of the base class.
  • Destructor
    • Derived then Base.

Casting: A pointer of a class can be cast to it’s derived or super class pointer.

  • Upcasting – Casting derived into a base class pointer
  • Downcasting – Casting base into a derived class pointer.. CAN BE DANGEROUS
  • Only base class part of the derived object can be seen through the base pointer.
  • Hence overridden functions will also not be called by a static cast.
  • Virtual Functions: 
    • In C++, dynamic binding is made possible only for pointer & reference data types and for methods that are declared as virtual in the base class.
    • Virtual functions are called through the VFT function pointer array
    • pointer to the array is stored in each object, as shown below.
    • Once a function is made virtual it will automatically be virtual in it’s derived classes, as the derived class inherits. Due to this, if there is no overridden function for that virtual function, the pointer to the virtual function of the base class will be stored in the VFT of derived class.
    • When a virtual function is called, the only information the compiler has is the VFT of the class in which it has been cast, hence the according index will be present in the compiled code, which in execution time will point to the VFT of the actual object.
    • Any class which has even one virtual function, a VFT will be created for that, and is called a Polymorphic Class.

VTable

  • Pure Virtual Functions… is a special syntax specified in C++ with which you can specify that you don’t have any definition for that member function, and hence don’t allow the construction of an object of the classes in which it is present.

Screen Shot 2014-02-12 at 11.36.34 pmType Casting:

  • used to convert the type of an object, expression, function argument, or return value to that of another type
  • (Silent) Implicit conversions and Explicit conversions.
  • To perform a type cast, the compiler:
    • allocates temporary storage
    • Initializes temporary with value being cast
  • Automatic Conversions:
    • The standard C++ conversions and user-defined conversions
    • Can be very handy,
    • And can also be unsafe at times
    • Overuse of user defined casting may lead to ambiguities
    • User defined casting can be obtained by either making a constructor of type A(B &) or operator A () in class B.

Alright, Alright, Alright! That would be all for this post. Remember that there is no better method for understanding a language than to code in it. Any mistakes or suggestions should be posted in the comments. Thanks for reading!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s