Pages

Tuesday, July 26, 2011

Overloading the '+' operator

#include
#include
class complex
{
int a,b;
public:
void getvalue()
{
cout<<"Enter the value of Complex Numbers a,b:";
cin>>a>>b;
}
complex operator+(complex ob)
{
complex t;
t.a=a+ob.a;
t.b=b+ob.b;
return(t);
}
complex operator-(complex ob)
{
complex t;
t.a=a-ob.a;
t.b=b-ob.b;
return(t);
}
void display()
{
cout<




}
};
void main()
{
clrscr();
complex obj1,obj2,result,result1;
obj1.getvalue();
obj2.getvalue();
result = obj1+obj2;
result1=obj1-obj2;
cout<<"Input Values:\n";
obj1.display();
obj2.display();
cout<<"Result:";
result.display();
result1.display();
getch();
}

Output:

Enter the value of Complex Numbers a, b
4 5
Enter the value of Complex Numbers a, b
2 2
Input Values
4 + 5i
2 + 2i
Result
6 + 7i
2 + 3i

Sunday, July 24, 2011

Overloading the < (less than) operator

#include
#include // For random number generator
#include // For time function
using std::cout;
using std::endl;

class Box {
public:
Box(double aLength, double aWidth, double aHeight):length(aLength), width(a
Width), height(aHeight) {}

double volume() const {
return length*width*height;
}

double getLength() const { return length; }
double getWidth() const { return width; }
double getHeight() const { return height; }

inline bool operator<(const Box& aBox) const {
return volume() < aBox.volume();
}

inline bool operator<(const double aValue) const {
return volume() < aValue;
}


private:
double length;
double width;
double height;
};


int main() {


Box firstBox(17.0, 11.0, 5.0);

if(firstBox < 100000){
cout << "less than";
}else{
cout << "not less than";
}

return 0;
}

Thursday, July 21, 2011

Operator Overloading Contd.

Operator overloading allows the programmer to define how operators (such as +, -, ==, =, and !) should interact with various data types. Because operators in C++ are implemented as functions, operator overloading works very analogously to function overloading.
Consider the following example:
1 int nX = 2;
2 int nY = 3;
3 cout << nX + nY << endl;
C++ already knows how the plus operator (+) should be applied to integer operands — the compiler adds nX and nY together and returns the result. Now consider this case:
1 Mystring cString1 = "Hello, ";
2 Mystring cString2 = "World!";
3 cout << cString1 + cString2 << endl;
What would you expect to happen in this case? The intuitive expected result is that the string “Hello, World!” is printed on the screen. However, because Mystring is a user-defined class, C++ does not know what operator + should do. We need to tell it how the + operator should work with two objects of type Mystring. Once an operator has been overloaded, C++ will call the appropriate overloaded version of the operator based on parameter type. If you add two integers, the integer version of operator plus will be called. If you add two Mystrings, the Mystring version of operator plus will be called.
Almost any operator in C++ can be overloaded. The exceptions are: arithmetic if (?:), sizeof, scope (::), member selector (.), and member pointer selector (.*). You can overload the + operator to concatenate your user-defined string class, or add two Fraction class objects together. You can overload the << operator to make it easy to print your class to the screen (or a file). You can overload the equality operator (==) to compare two objects. This makes operator overloading one of the most useful features in C++ -- simply because it allows you to work with your classes in a more intuitive way.
Before we go into more details, there are a few things to keep in mind going forward.
First, at least one of the operands in any overloaded operator must be a user-defined type. This means you can not overload the plus operator to work with one integer and one double. However, you could overload the plus operator to work with an integer and a Mystring.
Second, you can only overload the operators that exist. You can not create new operators. For example, you could not create an operator ** to do exponents.
Third, all operators keep their current precedence and associativity, regardless of what they're used for. For example, the bitwise XOR operator (^) could be overloaded to do exponents, except it has the wrong precedence and associativity and there is no way to change this.

Operator Overloading

There are two types of operators in C++ , Binary (that take 2 operands) and Unary (that take a single operand). Unary operators like ++ or - - and binary operators like +,-, * and / have a predefined task to perform. "+" can add two numericals, ">" can compare a value against other and so on. What if we want the operator to perform a customised task ? For example, using "+" to add to perform multiplication, "==" to function like "!=".  How can the functioning of an operator changed ? The answer is - using Operator Overloading.Using this concept an operator can be made to perform any task along with what it is supposed to do. Although it is not advisable to make "+" perform subtraction or to ask "==" to do any task other than equality comparison, but Operator Overloading can make it possible.
Operator overloading is the ability to tell the compiler how to perform a certain operation when its corresponding operator is used on one or more variables. For example, the compiler acts differently with regards to the subtraction operator “-“ depending on how the operator is being used. When it is placed on the left of a numeric value such as -48, the compiler considers the number a negative value. When used between two integral values, such as 80-712, the compiler applies the subtraction operation. When used between an integer and a double-precision number, such as 558-9.27, the compiler subtracts the left number from the right number; the operation produces a double-precision number. When the - symbol is doubled and placed on one side of a variable, such as --Variable or Variable--, the value of the variable needs to be decremented; in other words, the value 1 shall be subtracted from it. All of these operations work because the subtraction operator “-” has been reconfigured in various classes to act appropriately.

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.