Oop Mod2@Azdocuments - in 1
Oop Mod2@Azdocuments - in 1
functions). The ways of supporting function has changed and improved in C++ as compared to
C.Most of these changes are simple and straightforward.However there are a few changes which
require you to adopt a new way of thinking and organizing your program's code.Many of these
requirements were driven by object oriented facilities of C++.As we go along you would realise that
these facilities were invented to make C++ programs safer and more readable than their C
equivalents.Let us know the various issues involved in C++ functions.
A function prototype is a declaration that defines both : the arguments passed to the function and the
type of value returned by the function. If we were to call a function fool(
) which receives a float and int as arguments and returns a double value its prototype would look like
this:
double fool(float,int);
The C++ compiler uses the prototype to ensure that the types of the arguments you pass in a function
call are same as those mentioned in the prototype.If there is a mismatch the compiler points out
immediately.This is known as ,something which C lacks.
Without strong type checking,it is easier to pass illegal values to functions.For example,a non-
prototyped function would allow you to pass anint to a pointer variable,or a float to a long int.The
C++ compiler would immediately report such types of errors.In C++ prototypes do more than making
sure that actual arguments (those used in calling function) and formal arguments (those used in called
function) match in number,order and type.As we would see later,C++ internally generates names for
functions,including the argument type information.This information is used when several functions
have same names.
Remember that all functions in C++ must be prototyped.This means that every function must have its
argument list declared,and the actual definition of a function must exactly match its prototype in the
number,order and types of parameters.
Function Overloading
How does the C++ compiler know which of the abs( )s should be called when a call is made? It
decides from the type of the argument being passed during function call.For example,if an int is
being passed the integer version of abs( ) gets called,if a double is being passed then the double
version ofabs( ) gets called and so on.That's quite logical,you would agree.
What if we make a call like,
We have not declared abs( ) function to handle a char.Hence the C++ compiler would report an
error.If we want that this call should result into a call to the int version of abs( ),we must make use
of typecasting during the call,as shown below:
When we call the function box( ) with 4 arguments the box is drawn with the arguments
passed.However when we call it with 3 arguments the default value mentioned in the prototype
of box( ) is considered for the last argument.Likewise when we call the function with 2 arguments the
default values for the last 2 arguments are considered.Finally,when we call it with no arguments, a
box is drawn with all the default values mentioned in the prototype. Thus the default arguments are
used if the calling function doesn't supply them when the function is called.
Note: If one argument is missing when the function is called, it is assumed to be the last
argument.Thus,the missing arguments must be the trailing ones./you can leave out the last 3
arguments,but you cannot leave out the last but one and put in the last one.
a) While making a function call if you don't want to take the trouble of writing arguments which
almost always has the same value.
b) They are also useful in such cases where,after having written a program we decide to increase
the capabilities of a function by adding another argument.Using default arguments means that the
existing function calls can continue to use old number of arguments,while new function calls can use
more.
Using functions we can structure our programs in a more modular way, accessing all the potential
that structured programming can offer to us in C++.
A function is a group of statements that is executed when it is called from some point of the program.
The following is its format:
type name ( parameter1, parameter2, ...) { statements }
where:
type is the data type specifier of the data returned by the function.
name is the identifier by which it will be possible to call the function.
parameters (as many as needed): Each parameter consists of a data type specifier followed by
an identifier, like any regular variable declaration (for example: int x) and which acts within
the function as a regular local variable. They allow to pass arguments to the function when it
is called. The different parameters are separated by commas.
statements is the function's body. It is a block of statements surrounded by braces { }.
#include <iostream>
using namespace std;
int main ()
{
int z;
z = addition (5,3);
cout << "The result is " << z;
return 0;
}
Ans:
In order to examine this code, first of all remember something said at the beginning of this tutorial: a
C++ program always begins its execution by the main function. So we will begin there.
We can see how the main function begins by declaring the variable z of type int. Right after that, we
see a call to a function called addition. Paying attention we will be able to see the similarity between
the structure of the call to the function and the declaration of the function itself some code lines
above:
The parameters and arguments have a clear correspondence. Within the main function we called
to additionpassing two values: 5 and 3, that correspond to the int a and int b parameters declared for
function addition.
At the point at which the function is called from within main, the control is lost by main and passed
to functionaddition. The value of both arguments passed in the call (5 and 3) are copied to the local
variables int a and int b within the function.
Function addition declares another local variable (int r), and by means of the expression r=a+b, it
assigns to rthe result of a plus b. Because the actual parameters passed
for a and b are 5 and 3 respectively, the result is 8.
finalizes function addition, and returns the control back to the function that called it in the first place
(in this case,main). At this moment the program follows its regular course from the same point at
which it was interrupted by the call to addition. But additionally, because the return statement in
function addition specified a value: the content of variable r (return (r);), which at that moment had a
value of 8. This value becomes the value of evaluating the function call.
So being the value returned by a function the value given to the function call itself when it is
evaluated, the variable z will be set to the value returned by addition (5, 3), that is 8. To explain it
another way, you can imagine that the call to a function (addition (5,3)) is literally replaced by the
value it returns (8).
That, as you may already expect, produces the printing of the result on the screen.
The scope of variables declared within a function or any other inner block is only their own function
or their own block and cannot be used outside of them. For example, in the previous example it
would have been impossible to use the variables a, b or r directly in function main since they were
variables local to function addition. Also, it would have been impossible to use the variable z directly
within function addition, since this was a variable local to the function main.
Therefore, the scope of local variables is limited to the same block level in which they are declared.
Nevertheless, we also have the possibility to declare global variables; These are visible from any
point of the code, inside and outside all functions. In order to declare global variables you simply
have to declare the variable outside any function or block; that means, directly in the body of the
program.
#include <iostream>
using namespace std;
int main ()
{
int x=5, y=3, z;
z = subtraction (7,2);
cout << "The first result is " << z << '\n';
cout << "The second result is " << subtraction (7,2) << '\n';
cout << "The third result is " << subtraction (x,y) << '\n';
z= 4 + subtraction (x,y);
cout << "The fourth result is " << z << '\n';
return 0;
}
Ans:
In this case we have created a function called subtraction. The only thing that this function does is to
subtract both passed parameters and to return the result.
Nevertheless, if we examine function main we will see that we have made several calls to
function subtraction. We have used some different calling methods so that you see other ways or
moments when a function can be called.
In order to fully understand these examples you must consider once again that a call to a function
could be replaced by the value that the function call itself is going to return. For example, the first
case (that you should already know because it is the same pattern that we have used in previous
examples):
z = subtraction (7,2);
cout << "The first result is " << z;
If we replace the function call by the value it returns (i.e., 5), we would have:
z = 5;
cout << "The first result is " << z;
As well as
cout << "The second result is " << subtraction (7,2);
has the same result as the previous call, but in this case we made the call to subtraction directly as an
insertion parameter for cout. Simply consider that the result is the same as if we had written:
cout << "The second result is " << 5;
The only new thing that we introduced is that the parameters of subtraction are variables instead of
constants. That is perfectly valid. In this case the values passed to function subtraction are the values
of x and y, that are 5and 3 respectively, giving 2 as result.
The fourth case is more of the same. Simply note that instead of:
z = 4 + subtraction (x,y);
with exactly the same result. I have switched places so you can see that the semicolon sign (;) goes at
the end of the whole statement. It does not necessarily have to go right after the function call. The
explanation might be once again that you imagine that a function can be replaced by its returned
value:
z = 4 + 2;
z = 2 + 4;
Functions with no type. The use of void.
you will see that the declaration begins with a type, that is the type of the function itself (i.e., the type
of the datum that will be returned by the function with the return statement). But what if we want to
return no value?
Imagine that we want to make a function just to show a message on the screen. We do not need it to
return any value. In this case we should use the void type specifier for the function. This is a special
specifier that indicates absence of type.
#include <iostream>
using namespace std;
void printmessage ()
{
cout << "I'm a function!";
}
int main ()
{
printmessage ();
return 0;
}
Ans:
void can also be used in the function's parameter list to explicitly specify that we want the function to
take no actual parameters when it is called. For example, function printmessage could have been
declared as:
void printmessage (void)
{
cout << "I'm a function!";
}
Although it is optional to specify void in the parameter list. In C++, a parameter list can simply be
left blank if we want a function with no parameters.
What you must always remember is that the format for calling a function includes specifying its
name and enclosing its parameters between parentheses. The non-existence of parameters does not
exempt us from the obligation to write the parentheses. For that reason the call to printmessage is:
printmessage ();
The parentheses clearly indicate that this is a call to a function and not the name of a variable or some
other C++ statement. The following call would have been incorrect:
printmessage;
Until now, in all the functions we have seen, the arguments passed to the functions have been
passed by value. This means that when calling a function with parameters, what we have passed to
the function were copies of their values but never the variables themselves. For example, suppose
that we called our first function additionusing the following code:
int x=5, y=3, z;
z = addition ( x , y );
What we did in this case was to call to function addition passing the values of x and y,
i.e. 5 and 3 respectively, but not the variables x and y themselves.
This way, when the function addition is called, the value of its local
variables a and b become 5 and 3 respectively, but any modification to either a or b within the
function addition will not have any effect in the values of x and youtside it, because
variables x and y were not themselves passed to the function, but only copies of their values at the
moment the function was called.
But there might be some cases where you need to manipulate from inside a function the value of an
external variable. For that purpose we can use arguments passed by reference, as in the function
duplicate of the following example:
#include <iostream>
using namespace std;
int main ()
{
int x=1, y=3, z=7;
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z;
return 0;
}
Ans:
The first thing that should call your attention is that in the declaration of duplicate the type of each
parameter was followed by an ampersand sign (&). This ampersand is what specifies that their
corresponding arguments are to be passed by reference instead of by value.
When a variable is passed by reference we are not passing a copy of its value, but we are somehow
passing the variable itself to the function and any modification that we do to the local variables will
have an effect in their counterpart variables passed as arguments in the call to the function.
To explain it in another way, we associate a, b and c with the arguments passed on the function call
(x, y and z) and any change that we do on a within the function will affect the value of x outside it.
Any change that we do on bwill affect y, and the same with c and z.
That is why our program's output, that shows the values stored in x, y and z after the call to duplicate,
shows the values of all the three variables of main doubled.
i.e., without the ampersand signs (&), we would have not passed the variables by reference, but a
copy of their values instead, and therefore, the output on screen of our program would have been the
values of x, y and zwithout having been modified.
Passing by reference is also an effective way to allow a function to return more than one value. For
example, here is a function that returns the previous and next numbers of the first parameter passed.
#include <iostream>
using namespace std;
Ans:
When declaring a function we can specify a default value for each of the last parameters. This value
will be used if the corresponding argument is left blank when calling to the function. To do that, we
simply have to use the assignment operator and a value for the arguments in the function declaration.
If a value for that parameter is not passed when the function is called, the default value is used, but if
a value is specified this default value is ignored and the passed value is used instead. For example:
#include <iostream>
using namespace std;
int main ()
{
cout << divide (12);
cout << endl;
cout << divide (20,4);
return 0;
}
Ans:
As we can see in the body of the program there are two calls to function divide. In the first one:
divide (12)
we have only specified one argument, but the function divide allows up to two. So the
function divide has assumed that the second parameter is 2 since that is what we have specified to
happen if this parameter was not passed (notice the function declaration, which finishes with int b=2,
not just int b). Therefore the result of this function call is 6 (12/2).
there are two parameters, so the default value for b (int b=2) is ignored and b takes the value passed
as argument, that is 4, making the result returned equal to 5 (20/4).
Overloaded functions.
In C++ two different functions can have the same name if their parameter types or number are
different. That means that you can give the same name to more than one function if they have either a
different number of parameters or different types in their parameters. For example:
#include <iostream>
using namespace std;
int main ()
{
int x=5,y=2;
float n=5.0,m=2.0;
cout << operate (x,y);
cout << "\n";
cout << operate (n,m);
cout << "\n";
return 0;
}
Ans:
In this case we have defined two functions with the same name, operate, but one of them accepts two
parameters of type int and the other one accepts them of type float. The compiler knows which one to
call in each case by examining the types passed as arguments when the function is called. If it is
called with two ints as its arguments it calls to the function that has two int parameters in its
prototype and if it is called with two floats it will call to the one which has two float parameters in its
prototype.
In the first call to operate the two arguments passed are of type int, therefore, the function with the
first prototype is called; This function returns the result of multiplying both parameters. While the
second call passes two arguments of type float, so the function with the second prototype is called.
This one has a different behavior: it divides one parameter by the other. So the behavior of a call
to operate depends on the type of the arguments passed because the function has been overloaded.
Notice that a function cannot be overloaded only by its return type. At least one of its parameters
must have a different type.
inline functions.
The inline specifier indicates the compiler that inline substitution is preferred to the usual function
call mechanism for a specific function. This does not change the behavior of a function itself, but is
used to suggest to the compiler that the code generated by the function body is inserted at each point
the function is called, instead of being inserted only once and perform a regular call to it, which
generally involves some additional overhead in running time.
and the call is just like the call to any other function. You do not have to include the inline keyword
when calling the function, only in its declaration.
Most compilers already optimize code to generate inline functions when it is more convenient. This
specifier only indicates the compiler that inline is preferred for this function.
Recursivity.
Recursivity is the property that functions have to be called by themselves. It is useful for many tasks,
like sorting or calculate the factorial of numbers. For example, to obtain the factorial of a number (n!)
the mathematical formula would be:
n! = n * (n-1) * (n-2) * (n-3) ... * 1
#include <iostream>
using namespace std;
int main ()
{
long number;
cout << "Please type a number: ";
cin >> number;
cout << number << "! = " << factorial (number);
return 0;
}
Ans:
Notice how in function factorial we included a call to itself, but only if the argument passed was
greater than 1, since otherwise the function would perform an infinite recursive loop in which once it
arrived to 0 it would continue multiplying by all the negative numbers (probably provoking a stack
overflow error on runtime).
This function has a limitation because of the data type we used in its design (long) for more
simplicity. The results given will not be valid for values much greater than 10! or 15!, depending on
the system you compile it.
Declaring functions.
Until now, we have defined all of the functions before the first appearance of calls to them in the
source code. These calls were generally in function main which we have always left at the end of the
source code. If you try to repeat some of the examples of functions described so far, but placing the
function main before any of the other functions that were called from within it, you will most likely
obtain compiling errors. The reason is that to be able to call a function it must have been declared in
some earlier point of the code, like we have done in all our examples.
But there is an alternative way to avoid writing the whole code of a function before it can be used in
main or in some other function. This can be achieved by declaring just a prototype of the function
before it is used, instead of the entire definition. This declaration is shorter than the entire definition,
but significant enough for the compiler to determine its return type and the types of its parameters.
It is identical to a function definition, except that it does not include the body of the function itself
(i.e., the function statements that in normal definitions are enclosed in braces { }) and instead of that
we end the prototype declaration with a mandatory semicolon (;).
The parameter enumeration does not need to include the identifiers, but only the type specifiers. The
inclusion of a name for each parameter as in the function definition is optional in the prototype
declaration. For example, we can declare a function called protofunction with two int parameters
with any of the following declarations:
int protofunction (int first, int second);
int protofunction (int, int);
Anyway, including a name for each variable makes the prototype more legible.
#include <iostream>
using namespace std;
int main ()
{
int i;
do {
cout << "Type a number (0 to exit): ";
cin >> i;
odd (i);
} while (i!=0);
return 0;
}
Ans:
This example is indeed not an example of efficiency. I am sure that at this point you can already
make a program with the same result, but using only half of the code lines that have been used in this
example. Anyway this example illustrates how prototyping works. Moreover, in this concrete
example the prototyping of at least one of the two functions is necessary in order to compile the code
without errors.
The first things that we see are the declaration of functions odd and even:
void odd (int a);
void even (int a);
This allows these functions to be used before they are defined, for example, in main, which now is
located where some people find it to be a more logical place for the start of a program: the beginning
of the source code.
Anyway, the reason why this program needs at least one of the functions to be declared before it is
defined is because in odd there is a call to even and in even there is a call to odd. If none of the two
functions had been previously declared, a compilation error would happen, since either odd would
not be visible from even (because it has still not been declared), or even would not be visible
from odd (for the same reason).
Having the prototype of all functions together in the same place within the source code is found
practical by some programmers, and this can be easily achieved by declaring all functions prototypes
at the beginning of a program.
A function is a group of statements that together perform a task. Every C++ program has at least one
function which is main(), and all the most trivial programs can define additional functions.
You can divide up your code into separate functions. How you divide up your code among different
functions is up to you, but logically the division usually is so each function performs a specific task.
A function declaration tells the compiler about a function's name, return type, and parameters. A
function definition provides the actual body of the function.
The C++ standard library provides numerous built-in functions that your program can call. For
example, function strcat() to concatenate two strings, function memcpy() to copy one memory
location to another location and many more functions.
A function is knows as with various names like a method or a sub-routine or a procedure etc.
Defining a Function:
A C++ function definition consists of a function header and a function body. Here are all the parts of
a function:
Return Type: A function may return a value. The return_type is the data type of the value
the function returns. Some functions perform the desired operations without returning a value.
In this case, the return_type is the keyword void.
Function Name: This is the actual name of the function. The function name and the
parameter list together constitute the function signature.
Parameters: A parameter is like a placeholder. When a function is invoked, you pass a value
to the parameter. This value is referred to as actual parameter or argument. The parameter list
refers to the type, order, and number of the parameters of a function. Parameters are optional;
that is, a function may contain no parameters.
Function Body: The function body contains a collection of statements that define what the
function does.
Example:
Following is the source code for a function called max(). This function takes two parameters num1
and num2 and returns the maximum between the two:
return result;
}
Function Declarations:
A function declaration tells the compiler about a function name and how to call the function. The
actual body of the function can be defined separately.
For the above defined function max(), following is the function declaration:
Parameter names are not importan in function declaration only their type is required, so following is
also valid declaration: int max(int, int);
Function declaration is required when you define a function in one source file and you call that
function in another file. In such case you should declare the function at the top of the file calling the
function.
Calling a Function:
While creating a C++ function, you give a definition of what the function has to do. To use a
function, you will have to call or invoke that function.
When a program calls a function, program control is transferred to the called function. A called
function performs defined task and when its return statement is executed or when its function-ending
closing brace is reached, it returns program control back to the main program.
To call a function you simply need to pass the required parameters along with function name and if
function returns a value then you can store returned value. For example:
#include <iostream>
using namespace std;
// function declaration
int max(int num1, int num2);
int main ()
{
// local variable declaration:
int a = 100;
int b = 200;
int ret;
return 0;
}
return result;
}
I kept max() function along with main() function and complied the source code. While running final
executable, it would produce following result: Max value is : 200
Function Arguments:
If a function is to use arguments, it must declare variables that accept the values of the arguments.
These variables are called the formal parameters of the function.
The formal parameters behave like other local variables inside the function and are created upon
entry into the function and destroyed upon exit.
While calling a function, there are two ways that arguments can be passed to a function:
By default, C++ uses call by value to pass arguments. In general, this means that code within a
function cannot alter the arguments used to call the function and above mentioned example while
calling max() function used the same method.
Default Values for Parameters:
When you define a function you can specify a default value for for each of the last parameters. This
value will be used if the corresponding argument is left blank when calling to the function.
This is done by using the assignment operator and assigning values for the arguments in the function
definition. If a value for that parameter is not passed when the function is called, the default given
value is used, but if a value is specified this default value is ignored and the passed value is used
instead. Consider the following example:
#include <iostream>
using namespace std;
result = a + b;
return (result);
}
int main ()
{
// local variable declaration:
int a = 100;
int b = 200;
int result;
return 0;
When the above code is compiled and executed, it produces following result:
The call by reference method of passing arguments to a function copies the address of an argument
into the formal parameter. Inside the function, the address is used to access the actual argument used
in the call. This means that changes made to the parameter affect the passed argument.
To pass the value by reference, argument pointers are passed to the functions just like any other
value. So accordingly you need to declare the function parameters as pointer types as in the following
function swap(), which exchanges the values of the two integer variables pointed to by its arguments.
return;
}
To check the more detail about C++ pointers, kindly check C++ Pointers chapter.
For now, let us call the function swap() by passing values by reference as in the following example:
#include <iostream>
using namespace std;
// function declaration
void swap(int *x, int *y);
int main ()
{
// local variable declaration:
int a = 100;
int b = 200;
return 0;
}
When the above code is put together in a file, compiled and executed, it produces following result:
Function overloading in C++: C++ program for function overloading. Function overloading means
two or more functions can have the same name but either the number of arguments or the data type of
arguments has to be different, also note that return value has no role because function will return a
value when it is called and at compile time we will not be able to determine which function to call. In
the first example in our code we make two functions one for adding two integers and other for adding
two floats but they have same name and in the second program we make two functions with identical
names but pass them different number of arguments. Function overloading is also known as compile
time polymorphism.
int main()
{
long a, b, x;
float c, d, y;
x = add(a, b);
y = add(c, d);
return 0;
}
sum = x + y;
return sum;
}
sum = x + y;
return sum;
}
int main()
{
char first[] = "C programming";
char second[] = "C++ programming";
display(first);
display(first, second);
return 0;
}
By default, C++ matches a function call with the correct function definition at compile time. This is
called static binding. You can specify that the compiler match a function call with the correct
function definition at run time; this is called dynamic binding. You declare a function with the
keyword if you want the compiler to use dynamic binding for that specific function.
The following examples demonstrate the differences between static and dynamic binding. The first
example demonstrates static binding:
When function is called, function is called, although the argument refers to an object of
type . At compile time, the compiler knows only that the argument of function will be a
reference to an object derived from ; it cannot determine whether the argument will be a reference to
an object of type or type . However, this can be determined at run time. The following example is
the same as the previous example, except that is declared with the keyword:
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f() { cout << "Class B" << endl; }
};
int main() {
B x;
g(x);
}
Class B
The keyword indicates to the compiler that it should choose the appropriate definition
of not by the type of reference, but by the type of object that the reference refers to.
Therefore, a virtual function is a member function you may redefine for other derived classes, and
can ensure that the compiler will call the redefined virtual function for an object of the corresponding
derived class, even if you call that function with a pointer or reference to a base class of the object.
You redefine a virtual member function, like any member function, in any derived class. Suppose
you declare a virtual function named in a class , and you derive directly or indirectly from a
class named . If you declare a function named in class with the same name and same parameter
list as , then is also virtual (regardless whether or not you declare with
the keyword) and it overrides . However, if the parameter lists of and are
different, and are considered different, does not override , and is not
virtual (unless you have declared it with the keyword). Instead hides . The
following example demonstrates this:
#include <iostream>
using namespace std;
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A* pa1 = &b;
A* pa2 = &c;
// b.f();
pa1->f();
pa2->f();
}
The function is not virtual. It hides . Thus the compiler will not allow the function
call . The function is virtual; it overrides even though is not visible in .
If you declare a base class destructor as virtual, a derived class destructor will override that base class
destructor, even though destructors are not inherited.
The return type of an overriding virtual function may differ from the return type of the overridden
virtual function. This overriding function would then be called acovariant virtual function. Suppose
that overrides the virtual function . The return types of and may differ if all the
following conditions are met:
The function B::f returns a reference or pointer to a class of type T, and A::f returns a pointer
or a reference to an unambiguous direct or indirect base class of T.
The const or volatile qualification of the pointer or reference returned by B::f has the same or
less const or volatile qualification of the pointer or reference returned by A::f.
The return type of B::f must be complete at the point of declaration of B::f, or it can be of
type B.
#include <iostream>
using namespace std;
struct A { };
class B : private A {
friend class D;
friend class F;
};
A global_A;
B global_B;
struct C {
virtual A* f() {
cout << "A* C::f()" << endl;
return &global_A;
}
};
struct D : C {
B* f() {
cout << "B* D::f()" << endl;
return &global_B;
}
};
struct E;
struct F : C {
// Error:
// E is incomplete
// E* f();
};
struct G : C {
// Error:
// A is an inaccessible base class of B
// B* f();
};
int main() {
D d;
C* cp = &d;
D* dp = &d;
A* ap = cp->f();
B* bp = dp->f();
};
B* D::f()
B* D::f()
The statement calls and converts the pointer returned to type . The
statement calls as well but does not convert the pointer returned; the type
returned is . The compiler would not allow the declaration of the virtual
function because is not a complete class. The compiler would not allow the declaration of
the virtual function because class is not an accessible base class of (unlike friend
classes and , the definition of does not give access to its members for class ).
A virtual function cannot be global or static because, by definition, a virtual function is a member
function of a base class and relies on a specific object to determine which implementation of the
function is called. You can declare a virtual function to be a friend of another class.
If a function is declared virtual in its base class, you can still access it directly using the scope
resolution ( ) operator. In this case, the virtual function call mechanism is suppressed and the
function implementation defined in the base class is used. In addition, if you do not override a virtual
member function in a derived class, a call to that function uses the function implementation defined
in the base class.
A virtual function must be one of the following:
Defined
Declared pure
Defined and declared pure
A base class containing one or more pure virtual member functions is called an abstract class.
Operator Overloading is one of the most fascinating features of C++.It can transform,obscure
program listings into intuitive obvious ones.By overloading operators we can give additional
meaning to operators like +,*,-,<=,>=,etc. which by default are supposed to work only on standard
data types likeints,floats etc. For example if str1 and str2 are two character arrays holding strings
"Bombay" and "Nagpur" in them then to store "BombayNagpur" in a third string str3, in C we need
to perform the following operations:
No doubt this does the desired task but don't you think that the following form would have made
more sense:
Such a form would obviously not work with C,since we are attempting to apply the + operator on
non-standard data types (strings) for which addition operation is not defined. That's the place where
C++ scores over C,because it permits the + operator to be overloaded such that it knows how to add
two strings.
One of the important advantages of using functions is that they help us save memory space.As all the
calls to the function cause the same code to be executed;the function body need not be duplicated in
memory.
Imagine a situation where a small function is getting called several times in a program.As you must
be aware,there are certain overheads involved while calling a function.Time has to be spent on
passing values,passing control,returning value and returning control.In such situations to save the
execution time you may instruct the C++ compiler to put the code in the function body directly inside
the code in the calling program.That is, at each place where there is a function call in the source file,
the actual code from the function would be inserted, instead of jump to the function. Such functions
are called inline functions.
Function Pointers
A function pointer is a variable that stores the address of a function that can later be called through
that function pointer. This is useful because functions encapsulate behavior. For instance, every time
you need a particular behavior such as drawing a line, instead of writing out a bunch of code, all you
need to do is call the function. But sometimes you would like to choose different behaviors at
different times in essentially the same piece of code.
void (*foo)(int);
In this example, foo is a pointer to a function taking one argument, an integer, and that returns void.
It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is
a function, then foo must be a pointer to a function. (Similarly, a declaration like int *x can be read as
*x is an int, so x must be a pointer to an int.)
The key to writing the declaration for a function pointer is that you're just writing out the declaration
of a function but with (*func_name) where you'd normally just put func_name.
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int);
/* the ampersand is actually optional */
foo = &my_int_func;
return 0;
}
(Note: all examples are written to be compatible with both C and C++.)
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int);
foo = &my_int_func;
return 0;
}
Note that function pointer syntax is flexible; it can either look like most other uses of pointers, with
& and *, or you may omit that part of syntax. This is similar to how arrays are treated, where a bare
array decays to a pointer, but you may also prefix the array with & to request its address.
From the Linux man pages, we have the following declaration for qsort (from stdlib.h):
Note the use of void*s to allow qsort to operate on any kind of data (in C++, you'd normally
use templates for this task, but C++ also allows the use of void* pointers) because void* pointers can
point to anything. Because we don't know the size of the individual elements in a void* array, we
must give qsort the number of elements, nmemb, of the array to be sorted, base, in addition to the
standard requirement of giving the length, size, of the input.
But what we're really interested in is the compar argument to qsort: it's a function pointer that takes
two void *s and returns an int. This allows anyone to specify how to sort the elements of the array
base without having to write a specialized sorting algorithm. Note, also, that compar returns an int;
the function pointed to should return -1 if the first argument is less than the second, 0 if they are
equal, or 1 if the second is less than the first.
For instance, to sort an array of numbers in ascending order, we could write code like this:
#include <stdlib.h>
class Sorter
{
public:
virtual int compare (const void *first, const void *second);
};
and then you could pass in a pointer to an instance of the AscendSorter to cpp_qsort to sort integers
in ascending order.
Syntax
Declare a function pointer as though you were declaring a function, except with a name like *foo
instead of just foo:
void (*foo)(int);
Initializing
You can get the address of a function simply by naming it:
void foo();
func_pointer = foo;
void foo();
func_pointer = &foo;
Invoking
Invoke the function pointed to just as if you were calling a function.
or you may optionally dereference the function pointer before calling the function it points to:
Function pointers provide a way of passing around instructions for how to do something
You can write flexible functions and libraries that allow the programmer to choose behavior
by passing function pointers as arguments
This flexibility can also be achieved by using classes with virtual functions
d = j;
}
ARRAYS, POINTERS, AND REFERENCES
Objects are variables and have the same capabilities and attributes as any other type of variables.
Therefore, it is perfectly acceptable for objects to be arrayed. The syntax for declaring an array of
objects is exactly as that used to declare an array of any other type of variable. Further, arrays of
objects are accessed just like arrays of other types of variables.
If the class type include a constructor, an array of objects can be initialised,
Reference and Bibliography
1.
2.
3.
4.
5.