Pages

Sunday, July 17, 2011

Function Overloading

he overloaded functions in the previous example differed in the type of their arguments. It is also possible to overload functions if their number of arguments differs. For example:
float FindMax(float a, float b);
float FindMax(float a, float b, float c);
int FindMax(int a, int b);
and so on.

Functions differing only in their return type cannot be overloaded. Since the returned value may be implicitly converted, the compiler cannot resolve which version the programmer intended to use. The following code causes a compilation error.

int FindAverage(float a, float b, float c);
    //Returns a rounded "average" as an int
float FindAverage(float a, float b, float c);
    //Returns the double average

int main()
{

    int avg;
    float a = 5.0;
    float b = 5.5;
    float c = 6.0;

    avg = FindAverage(a, b, c);

    return 0;
}

The compiler cannot determine whether the programmer intended:
1) To use the float version of FindAverage and then truncate the return value and assign to avg.
2) To use the int version of FindAverage, which returns a rounded average as an int.


Cases where overloading should not be used
1) If the functions to be overloaded perform distinct operations, then overloading will mask this uniqueness and make their proper use harder.

Suppose there are two functions to find a minimum value, one for float arguments and another for integer arguments. Further suppose that the minimum value function for integers is to return either the minimum, or zero if the minimum is less than zero, while the minimum value function for floats returns the minimum regardless of sign. If they are implemented as overloaded functions then it is easy to forget the extra bound on the integer version.

Use:
int FindMinOrZero(int a, int b);    //Or some similar name
float FindMin(float a, float b);

Rather than:
int FindMin(int a, int b);
float FindMin(float a, float b);

This distinct functionality is more apparent using distinct identifiers.

2) A single function with default arguments can replace the overloaded functions.
Suppose that an "integer" FindMax function is needed and that it can take either two or three arguments. Also, assume that if will return zero if all the arguments are negative. 

Use:
float FindMax(float a, float b, float c = 0);

Rather than:
float FindMax(float a, float b);
float FindMax(float a, float b, float c);

This results in only a single function to learn to use and to maintain. 
3) Function templates offer a cleaner design.
Function templates are covered in the next lesson. They offer a way to parameterize arguments that differ only by type. The net result is that a single function template can sometimes replace several overloaded versions of a function.

Method Overloading Without A Class

#include


void ConvertFToC(double f, double &c);
void ConvertFToC(float f, float &c);
void ConvertFToC(int f, int &c);

int main()
{
    double df, dc;
    float ff, fc;
    int i_f,i_c;    //if is a reserved word

    df = 75.0;
    ff = 75.0;
    i_f = 75;

    
    cout << "Calling ""double"" version" << endl;
    ConvertFToC(df,dc);
    cout << df << " == " << dc << endl << endl;

    cout << "Calling ""float"" version" << endl;
    ConvertFToC(ff,fc);
    cout << ff << " == " << fc << endl << endl;

    cout << "Calling ""int"" version" << endl;
    ConvertFToC(i_f,i_c);
    cout << i_f << " == " << i_c << endl << endl;

}


void ConvertFToC(double f, double &c)
{
    cout << "In ""double"" version" << endl;
    c = (f - 32.0) * 5. / 9.;
}

void ConvertFToC(float f, float &c)
{
    cout << "In ""float"" version" << endl;
    c = (f - 32.0) * 5. / 9.;
}

void ConvertFToC(int f, int &c)
{
    cout << "In ""int"" version" << endl;
    c = (f - 32) * 5. / 9.;
}

Friday, July 15, 2011

Polymorhpism - Function Overloading

As mentioned in the previous post, polymorphism is the ability of an object to behave differently in different conditions. To practically implement the concept of polymorphism in C++ one of two methods is Function Overloading.


Function Overloading
To put it simply , function overloading is declaring two or more functions with the same. The idea behind using the same name for multiple methods is to save the user from the trouble of remembering different names for different methods. For example, if there is a method that adds two integers the most suitable name will be "add" or "sum" or any other logical name. Imagine another method that adds two float values, or another one that adds three integers. One way of naming all these methods will be assigning different name to all the methods like "add1","add2", "add3", but it will make the whole process very confusing. Since all the methods are doing similar tasks(addition) the concept of function overloading will make the task easy for us by allowing  same name for all these functions. 

Calling overloaded functions

Since all the functions have same name, how will the compiler decide which method to call. The answer is - by looking at the arguments. All the overloaded functions must be 
a) In The Same Class : You can not declare two functions with the same name in a parent and a child class and call it "Overloaded".
b) Their arguments must be different : The methods must differ in either number, datatype or order.

Example
In general functions are overloaded when :
1. Functions differ in function signature. 
2. Return type of the functions is the same.
Here s a basic example of function overloading
  1. #include
  2.  
  3.  
  4. class sample {
  5. public:
  6.  void calc(int num1)
  7.  
  8. {
  9. cout<<"Square of a given number: " <<num1*num1 <<endl;
  10. }
  11.  
  12.  void calc(int num1, int num2 )
  13.  
  14. {
  15. cout<<"Product of two whole numbers: " <<num1*num2 <<endl;
  16. }
  17. };
  18.  
  19.  
  20. int main()  
  21. {
  22.     sample s;
  23.     s.calc(2);
  24.     s.calc(2,3);
  25. }
First the overloaded function in this example is calc. If you have noticed we have in our sample class two functions with the name calc. The fist one takes one integer number as a parameter and prints the square of the number. The second calc function takes two integer numbers as parameters, multiplies the numbers and prints the product. This is all we need for making a successful overloading of a function.
a) we have two functions with the same name : calc
b) we have different signatures : (int) , (int, int)
c) return type is the same : void

The result of the execution looks like this
  1. Square of a given number: 25
  2. Product of two whole numbers: 42
The result demonstrates the overloading concept. Based on the arguments we use when we call the calc function in our code :
  1. s.calc(5);
  2. s.calc(6,7);
The compiler decides witch function to use at the moment we call the function. Remember that argument name of the methods and the return value does not matter in the whole process.

Thursday, July 14, 2011

Polymorphism

One of the important features of any programming language like C++ is "Polymorphism". Poly means "many" and "morphos" means "forms". Therefore, Polymorhism is essentially the ability of an object to take many or multiple forms as per the context.

Polymorphism is not a concept of OOPS or programming only, in real life there are many examples of the same theory. Take for example the english word "bank", in the language it can stand for a money bank or bank of a river. What exactly the word means can only be understood by looking at the context. For example if there is talk going on about money or other monetary issue the word can be for the financial bank.

In C++, the word mainly stands for collectively referring to two activities or concepts - Function or method overloading and Operator Overloading.

Function Overloading : In C, it is not possible to declare two functions with the same name. For example, if a program has a function named "show()", the same name cannot be used for declaring another function. In C++, it is possible. The process of declaring two or more methods with the same name is called "Function Overloading". But there is a catch, all the functions with the same name must be different in their "signature". The term signature implies that the functions must be different in their arguments. All the functions that are intended to be overloaded must be differ in any of the following
a) Different number of arguments
b) Different datatypes of arguments
c) Order of arguments

Operator Overloading : There are two types of operators
a) Unary and
b) Binary

The unary operator are those operators that take a single operand as argument. For example ++ and --, whereas Binary operators are those operators that take two operands, for example +, - , * , / etc.

Every operator has a specific task. For example '+' adds two numericals, '-' subtracts the values etc. Operator overloading the ability of an operator to change the basic function of an operator to perform any other function other than its core task.

Wednesday, July 6, 2011

Parameterized constructors in inheritance

Special attention must be paid when it comes to base classes having parameterized constructors.  When we declare a base class that has a parameterized constructor, the parameters can not be passed through the child class object directly. In other words, a child class object can not pass arguments to its base class constructor. So how would you call the base class constructor then ? The answer is by declaring a child class parameterized constructor.

Look at the following code

class base
{
public:
 base (int a)
 {
  cout<<"\nCalling Base Class Constructor with the value "<

class child : public base
{
public:
 child(int b) : base(b)
 {
  cout<<"\nThe same argument can be used here as well "<
void main()
{
 child c(10);
 }

Here is the output :

Calling Base Class Constructor with the value 10
The same argument can be used here as well 10

This is how it worksThe base class has a constructor which has an int parameter named "a", when we declare an object of the child class, the value (10) is passed to the argument "b" of the child class. From here the statement "base(b)" passes the value of "b" to the parent class constructor where the value is copied to the argument "a". The base class constructor prints the value as needed. The same value if required can be used in the child class constructor as well.
The summary is "The child class constructor must pass all the required arguments to the base class constructor".

Let's see a more practical example

class vehicle
{
 char vname[10],type[10];
public:
 vehicle(char vnm[],char ty[])
 {
  strcpy(vname,vnm);
  strcpy(type,ty);
 }
 void show_veh() {
  cout<<"\nVehicle Name : "<
public:
 car(char vnm[],char ty[],char mk[],int m) : vehicle (vnm,ty)
 {
  strcpy(make,mk);
  model=m;
 }
 void show_car()
 {
  show_veh();
  cout<<"\nMake : "<
void main()
{
 car mycar("City","Sports","Honda",2011);
 mycar.show_car();
}
As you can see there is a base class(vehicle) which has a parameterized constructor. There is another parameterized constructor in the child class (car). The child class has only two properties namely, make and model therefore its constructor should be interested only in initializing only these two properties but since the base class constructor will be the first one to be invoked it is the responsibility of the child class to provide the the parameters to the base class. Therefore the constructor of the child class has declared four arguments, 2 for itself and 2 for its base class.

Saturday, July 2, 2011

Constructor In Inheritance

Constructor In Inheritance
With reference to inheritance, one important point to learn is how the constructors behave during the inheritance process.

When a child class inherits from a base class and base class has a constructor, it will always run first when the object of the child class in declared. If the child class too has a constructor it will always run after the base class constructor. In a nutshell "The order of constructor invocation in inheritance will be base class followed by the child class". In multiple inheritance where a child class is derives its behaviour from more than one classes, the order of invocation will be the same as order of inheritance.
For example, in the syntax
class child : public base1,public base2

the constructor of "base1" will be processed first followed by the "base2" constructor. The constructor of the "child" class will always be the last one to processed.

Constructor in Single Inheritance

Consider the following code snippet

class base
{
public:
 base()
 {
  cout<<"\nBase Class Constructor";
 }
}
class derived : public base
{
public:
 derived()
 {
  cout<<"\nDerived Class Constructor";
 }
}

When the above code is compiled  the output shown will be
Base Class Constructor
Derived Class Constructor

Here’s what actually happens when the base is instantiated:
  1. Memory for Base is set aside
  2. The appropriate Base constructor is called
  3. The initialization list initializes variables
  4. The body of the constructor executes
  5. Control is returned to the caller
Here’s what actually happens when Derived is instantiated:
  1. Memory for Derived is set aside (enough for both the Base and Derived portions).
  2. The appropriate Derived constructor is called
  3. The Base object is constructed first using the appropriate Base constructor
  4. The initialization list initializes variables
  5. The body of the constructor executes
  6. Control is returned to the caller

The only real difference between this case and the non-inherited case is that before the Derived constructor can do anything substantial, the Base constructor is called first. The Base constructor sets up the Base portion of the object, control is returned to the Derived constructor, and the Derived constructor is allowed to finish up it’s job.

 

Wednesday, June 29, 2011

Types Of Inheritance

Inheritance Types

There are many different types of inheritances each with its own features and benefits. The following are the types of inheritances available in C++.
  •  Single Inheritance
Single Inheritance (Base Class - A, Child Class B)

When a child class is declared using the properties of a single base class, it is known as Single Inheritance. In this type of inheritance, the child class can access all the public and protected members of the parent as if they are its own.
Syntax
class child : access_specifier baseclass

Example
class student : public person

  •  Multiple Inheritance
Multiple Inheritance : Base Classes A & B
Child Class - C
When a child class is declared using the properties of more than one base class, it is termed as Multiple inheritance. In this case, the child class benefits more than it does in Single Inheritance since now it can access the members of more the one class. A class can inherit from as many classes as required. Similar to Single Inheritance, the child class can access only the  public and protected members of its parents.


Syntax
class child : access_specifier baseclass1, access_specifier baseclass2....
Example
class bike : public vehicle, public automobile

  • Multilevel Inheritance
B is both a parent and
a child
If a child class also acts as a parent class for another class, it is called Multilevel inheritance. In this type of Inheritance the intermediate class is both a child and a parent. 
In this type of inheritance, there are number of level and it has used in that cases where we want to use all properties in number of levels according to the requirement. For example, class A inherited in class b and class b has inherited in class c for class b so on. Where class A is base class c. In another way we can say b is derived class a base class for c and a indirect base class for c is indirect base class for c and c indirect derived class for class A.



  • Hierarchical Inheritance:
Class A has multiple child classes
This type of inheritance helps us to create a baseless for number of classes and those numbers of classes can have further their branches of number of class.

  • Hybrid Inheritance:
In this type of inheritance, we can have combinations of different types of inheritances. For example if there are many classes in a program some of them single inheritance while others can have multiple inheritance.