You are on page 1of 19

Overloading and Inline Function in C++

Completed by Firas M. Kadhum


Iraq - Baghdad

TABLE OF CONTENTS
TITLE PAGE NO.

List of Tables .... 1 List of Figures..1 Introduction ..... 2 1- Overloading operators .....3 1-1 Defining operator overloading.....4 1-2 Overloading unary operators ......7 1-3 Overloading binary operators......10 2- Overloading function ......12 3- Inline function .....16 3-1 What is inline function..........16 3-2 Advantage and disadvantage .......16 3-3 General format of inline function .........16 3-4 inline function implementation .......17 References ..18

List of Tables
[Table (1): C++ places in the programming languages]... 2 [Table (2): Unary operators] ... 5 [Table (3): Binary operators] .. 5

List of Figures
[Figure (1): Structure of C++ program]... 2 [ Figure (2): The general syntax of an operator function] ...4 [Figure (3): The general format of inline function]... 16

Introduction:
C++ is an object oriented language . Initially named C with classes . This language was developed by Bjarne Stroustrup at Bell labs in Murray Hill, New jersy , USA in the early eighties. C++ is often called a middlelevel computer language, which it means that is combines elements of highlevel languages with the functionalism of assembly language. The table (1) below show C++ fits into spectrum of languages. Level Highest-level Middle-level Lowest-level languages PASCAL , BASIC , FORTRAN C++ , C , Macro-assembly Assembly language
Table (1): C++ places in the programming languages

C++ is a Superset of C , Therefore almost all C programs are also C++ programs. In other words: When Bjarne Stroustrup designed C++, he added OOP (Object Oriented Programming) features to C without significantly changing the C component. Thus C++ is a "relative" of C, meaning that any valid C program is also a valid C++ program. The program in C++ language would contain four sections as show in the following figure (1).
Include files Class declaration Class functions definitions Main function program

Figure (1): Structure of C++ program

The One of the important features of OPP, it is Polymorphism. It simple means one name, multiple forms. Polymorphism can be applied in the C++ language in two cases: either during run-time (dynamic binding) or during compile-time (static binding).The latter case is applied in two methods: The
2

first method is called overloading operators using some operators in C++. And the second method is called overloading functions using functions. Therefore I will cover these methods with some examples that show this property useful and difficult at the same time.

1 - Overloading operators:
C++ has a number of built-in types, including int, real, char, and so forth. Each of these has a number of built-in operators, such as addition (+) and multiplication (*).The operators are symbols. C++ has more than 40 operators. C++ enables you to add these operators to your own classes as well. Almost all C++ operators can be overloaded. 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 suitably. The Overloading an operator means having two or more definitions for an operator. C++ treats operators as special kinds of functions. Operator overloading is a very important feature of Object Oriented Programming. Curious to know why!!? It is because by using this facility programmer would be able to create new definitions to existing operators. In fact in other words a single operator can take up several functions as desired by programmers depending on the argument taken by the operator by using the operator overloading facility. After knowing about the feature of operator overloading now let me see how to define and use this concept of operator overloading in C++ programming language.
3

1-1 Defining operator overloading:


In C++, to define additional meanings for predefined operators to overload them . This definition is just like an ordinary function definition except the name of the function begins with the keyword operator and ends with the operator itself. Thats the only difference, and it becomes a function like any other function, which the compiler calls when it sees the suitable pattern. This special function is called operator function. The general syntax of an operator function as show in the following figure(1). <return_type> operator <operator_symbol> ( arguments_list ) { function body ; }
Figure (2): The general syntax of an operator function

Where: <return_type> : is the type of the value returned by the specified operation; operator : is the keyword; <operator_symbol> : is the operator being loaded,[you can see it in table2,3]; arguments_list : represent the list of arguments (parameters) . Operator function must be either member function or a friend function. The basic difference between these functions is that a friend function will have only one argument for unary operators and two for binary operators. While a member function has no arguments for unary operators and only one for binary operators. This is because the object used to invoke the member function is passed implicitly and therefore is available for the member function.

Broadly classifying operators are of two types namely: Unary Operators Binary Operators The unary operators are shown in the following table (2):
Operator ! & ~ * + ++ -conversion operators Logical NOT Address-of One's complement Pointer dereference Unary plus Increment Unary negation Decrement conversion operators Name

The Binary operators are shown in the following table (3):


Operator , != % %= & && &= * *= + += Comma Inequality Modulus Modulus/assignment Bitwise AND Logical AND Bitwise AND/assignment Multiplication Multiplication/assignment Addition Addition/assignment Subtraction Name

= > >* / /= < << <<= <= = == > >= >> >>= ^ ^= | |= ||

Subtraction/assignment Member selection Pointer-to-member selection Division Division/assignment Less than Left shift Left shift/assignment Less than or equal to Assignment Equality Greater than Greater than or equal to Right shift Right shift/assignment Exclusive OR Exclusive OR/assignment Bitwise inclusive OR Bitwise inclusive OR/assignment Logical OR

Notes: 1- The = , ( ), [ ] and -> operators must be defined as member functions. 2- The next five operators cannot be overloaded: :: ( scope resolution operator ) . ( member selection ) .* ( member selection through pointer to function ) sizeof ( size of operator ) ?: ( conditional operator ) 3- You cannot combine operators that currently have no meaning in C++ (such as ** to represent exponentiation).
6

4- You cannot change the number of arguments an operator. 5- You cannot use a symbol that isnt operator, like @ or $. 6- To avoid the copying of large objects when passing them to an overloaded operator, references should be used. Pointers are not suitable for this purpose because an overloaded operator cannot operate exclusively on pointers.

1-2 Overloading unary operators:


Unary operators act on only one operand. Some commonly used unary operators are unary minus (-), increment (++) and decrement (--) operators. Let me start by overloading the unary minus operator. The unary minus operator changes the sign of an operand when applied to basic data-type (int, float, double etc.). The following program, demonstrates how to overload this operator, so that it can be applied to an object in much the same way as is applied to an int or float type variable. The Program:
//***This program illustrates the overloading of unary operator(-) as member function*** # include <iostream.h> class minus { int x,y,z ; public: void getdata (int a , int b , int c ); // Declaration of the getdata function void display (void) ; void operator ( ) ; }; // Declaration of the display function // Declaration of the operator function as member function // End of the Class Definition

//***********Member Function Definitions************* void minus :: getdata ( int a , int b , int c ) { x=a; y=b; z=c; } void minus :: display ( void ) { cout << "\t x = " << x << endl ; cout << "\t y = " << y << endl ; cout << "\t z = " << z << endl ; } //*********Definition of the operator function *********** void minus :: operator - ( ) { x = -x ; y = -y ; z = -z ; } //*************Main Function Definition**************** main( ) { minus M ; M.getdata ( 10 , -20,30 ) ; cout << " \n M : Before activating the operator - ( ) \n"; M.display( ) ; -M; // operator invoked ( call of operator function ) cout << "\n M : After activating the operator - ( )\n" ; M.display( ) ; }

The output:
M : Before activating the operator - ( ) x = 10 y = -20 z = 30 M : After activating the operator - ( ) x = -10 y = 20 z = -30 In the program above, the declarative of the operator function is given as: void operator ( ) ;

This declarative tells the compiler to call this member function , whenever the operator is encountered, provided the operand is of type minus. The function operator ( ) takes no argument. This function is a member function, and the member functions can directly access the members of an object for which they have been called. Therefore, the operator function for overloading the unary minus operator ( - ) does not require any argument. In other words: Whenever an unary operator is used, it works with one operand, therefore with the user defined data types, the operand becomes the caller and hence no arguments are required In the main( ) function of this program, the object M of type minus is declared and initialized to ( 10, -20, 30 ) as: minus M( 10, -20, 30 ) ; Before activating the operator function, the values of a, b and c are displayed as: x = 10 y = -20 z = 30 After the statement -M; The object M invokes the operator member function unary minus. the function will change the sign of all the data members of the object M. the operator member function gets activated and the values of x, y and z are displayed as: x = -10 y = 20 z = -30 A statement such as M1 = - M2 will yield a compiler error since the unary minus member function is not designed to return any value; however, with a little modification this function will be able to return values. It is possible to overload an unary minus operator in above program using a friend function. This can be done ,just change the declaration and definition of the operator function as follows: friend void operator ( minus & M ); // Declaration as friend function And for definition : void operator ( minus & M) { M.x = - M.x ; M.y = - M.y ; M.z = - M.z ; } The argument must pass by reference because any change to the values it accepted, in other words: Note: In the above definition, we have received the operand by reference because we need to change the values of its data members, which would not be possible if we would receive the argument by value.
9

1-3 Overloading binary operators:


Binary operators act with two operands. The operator function defined for binary operator overloading, as unary operator overloading, can be member function or friend function. The difference is in the number of arguments used by the function. In the case of binary operator overloading, when the function is a member function then the number of arguments used by the operator function is one. When the function defined for the binary operator overloading is a friend function, then it uses two arguments (one of those arguments must be either a class object or a reference to a class object). Some commonly used binary operators are (+) addition,(-) subtraction and (*) multiplication operators. Let me start by overloading the (+) addition operator. The following program, demonstrates how to overload this operator.
int a,b,c ; c=a+b; This is clearly valid code in C++, since the different variables of the addition are all fundamental types. Concerning the usage of types defined by the user, we couldnt use similarly the + operator. For example: we declare a new type to represent complex numbers. A complex number, z, consists of the ordered pair (re, im), re is the real component and im is the imaginary component of the number. Class complex { float re,im; public : complex ( float real=0 , float imag=0 ) { re=real ; im=imag Void print ( ) { cout << the real is << re <<\n ; Cout << the imag is << im <<\n; } // constructor // re = real part , im=imaginary part

10

} }; complex a , b , c; c=a+b; This cod will cause a compilation error, since I have not defined the behavior my class should have with addition operations. To perform operations like addition and so on, is necessary to define functions such the below program . // End of the Class Definition

The Program :
//***This program illustrates the overloading of binary operator(+) as member function*** # include <iostream.h> class complex { float re, im; // re = real part, im = imaginary part public: complex ( float real=0 , float imag =0 ) { re = real ; im = imag } void display ( void ) ; complex operator + ( complex op) ; }; // Declaration of the display function // Declaration of the operator function as member function // End of the Class Definition // constructor

//***********Member Function Definitions************* void complex :: display (void) { cout << re << + j << im <<\n; } //*********Definition of the operator function *********** complex complex :: operator + (complex op ) { complex temp ; temp.re = re + op.x ; temp.im = im + op.im ; return (temp) } //*************Main Function Definition**************** main( ) {
11

complex c1,c2,c3 ; c1= complex (2.5 , 3.5) ; c2 = complex ( 1.6 , 2.7); c3 = c1 + c2 ; cout << " \n c1= ; c1.display ( ); cout << c2 = ; c2.display ( ) ; cout << c3 = ; c3.dispaly ( ) }

// operator invoked ( call of operator function )

The output :
c1 = 2.5 +j 3.5 c2 = 1.6 +j 2.7 c3 = 4.1 +j 6.2 Note : only one object can access directly , in the program above: c3 = c1 + c2 is equivalent to : c3 = c1.opertaor + ( c2) It is possible to overload binary addition operator in above program using a friend function. This can be done ,just change the declaration and definition of the operator function as follows: friend complex operator + ( complex , complex ); // Declaration as friend function And for definition: complex operator + ( complex a , complex b) { complex temp ; temp.re = a.re + b.re ; temp.im = a.im + b.im ; return ( temp) }

2 - Overloading function:
C++ enables you to create more than one function with the same name. This is called function overloading. The functions must differ in their parameter list, with a different type of parameter, a different number of parameters, or both. Here's an example (1): int myFunction (int, int) ;

12

int myFunction (long, long) ; int myFunction (long) ; myFunction( ) is overloaded with three different parameter lists. The first and second versions differ in the types of the parameters, and the third differs in the number of parameters. The return types can be the same or different on overloaded functions, as long as the parameter list is different. You can't overload just on return type, however.

Function polymorphism refers to the capability to overload a function with more than one meaning. By changing the number or type of the parameters, you can give two or more functions the same function name, and the right one will be called by matching the parameters used. Suppose you write a function that doubles whatever input you give it. You would like to be able to pass in an int, a long, a float, or a double. Without function overloading, you would have to create four function names: int DoubleInt(int) ; long DoubleLong(long) ; float DoubleFloat(float) ; double DoubleDouble(double) ; With function overloading, you make this declaration: int Double(int) ; long Double(long) ; float Double(float) ; double Double(double) ; This is easier to read and easier to use. You don't have to worry about which one to call; you just pass in a variable, and the right function is called automatically. Finally, a function is overloaded when same name is given to different function. However, the two functions with the same name will differ at least in one of the following. a) The number of parameters. b) The data type of parameters.

13

These two together are referred to as the function signature.

Here's an example (2):

The program:
//*******************This program illustrates the function overloading************ # include <iostream.h> int volume ( int ) ; double volume (double , int ); long volume (long , int , int ) ; int main ( ) { Cout << \n The volume = << volume (10) << \n ; Cout << The volume = << volume ( 2.5,8 ) << \n ; Cout << The volume = << volume (100,75,15) ; } //************* Function Definitions **************** // The volume of the cube is L3 = L L L int volume ( int d ) { return ( d * d * d ) ; } // The volume of the cylinder is length pi (radius)2 double volume (double r , int L) { return (3.14 * r * r * L) ; } // The volume of the rectangle is length x height x width long volume (long L , int h , int w ) { return ( L * h * w ) ; } // prototype (1) // prototype (2) // prototype (3)

The output :
The volume = 1000 The volume = 157 The volume = 112500
14

Here's an example (3): // declarations : int add ( int a , int b ) ; int add ( int a , int b , int c ) ; double add ( double x , double y ) ; double add ( int p , double q ) ; // function calls cout << add (5 , 10) ; cout << add (5 , 10.0) ; cout << add (12.5 , 7.5) ; cout << add (5 , 10 , 15) ; // use prototype 1 // use prototype 4 // use prototype 3 // use prototype 2 // prototype (1) // prototype (2) // prototype (3) // prototype (4)

Selection function is as the following steps: 1 - First, the compiler tries to find a function exactly (exact match) the same types used in the actual parameters. 2- If the compiler did not find exact match, it will change actual parameters automatically such as ( chat to int ) or ( float to double ). 3-When a failure in the previous two steps, the compiler attempts to use the built-in conversions. The complier will send error at the time. If the result of process of conversion has a several matches. Here's an example (4): long square ( long n ) ; // declaration

double square ( double x ) ; // declaration And : square ( 10 ) ; // call of function square

Note : will be an error occurs since the compiler maybe will convert the integer to long or double.
15

3 Inline functions:
3-1 What is Inline Function? Inline functions are functions where the call is made to inline functions. The actual code then gets placed in the calling program. 3-2 Advantage and disadvantage: In order to optimize the program for better speed , we can use inline function to chive this goal, this function duplicate the function into main program in order to get vide of the translation of the compiler from main function to sub function the function advantage is when the sub function is small (one or two statements ).In other word , What's the rule of thumb? If you have a small function, one or two statements, it is a candidate for inline. When in doubt, leave it out. Note that inline functions can bring a heavy cost. For example, If the function is called 10 times, the inline code is copied into the calling functions each of those 10 times. The tiny improvement in speed you might achieve is more than swamped by the increase in size of the executable program. Even the speed increase might be illusory. 3-3 General Format of inline Function: If a function is declared with the keyword inline, the compiler does not create a real function: It copies the code from the inline function directly into the calling function. No jump is made; it is just as if you had written the statements of the function right into the calling function.The general format of inline function is as follows: inline function_header { function_body; }

16

Figure (3): The general format of inline function

Heres an example : inline double cube ( double n ) { return ( n * n * n ) }

3- 4 Inline Function implementation: We can make class method inline. The keyword inline appears before the return value. For example,
inline int cat :: getweight( ) { return itswight ; } // inline // return the weight data member of class cat

We can also put the definition of a function into the declaration of the class, which automatically makes that function inline. For example,
Class cat { Public : int getweight () { return itsweight ; } void setweight( ) ( int weight ) ; }; // end of class // Automatically makes function inline

Note: There is no semicolon after the paren-theses .Like any function.

17

References :
[1] J. Liberty, Teach Yourself C++ in 24 Hours, first Edition, Sams ,USA ,pp. 8592:220-236 , 1997. [2] H. Sutter and Paul J. Deite, C++ How to Program , seventh Edition, person eduction Ltd.,USA ,pp. 467-509, 2009. [3] Safari books online , , http://my.safaribooksonline.com/programming.

[4] S. Oualline , Practical programming C++ , second Edition, OReily ,USA ,pp. 310-345, 2009.

18

You might also like