Home | | Object Oriented Programming | Functions and Pointers

Chapter: Object Oriented Programming(OOP) : Overview

Functions and Pointers

A function, which can also be referred to as subroutine, procedure, subprogram or even method, carries out tasks defined by a sequence of statements called a statement block that need only be written once and called by a program as many times as needed to carry out the same task.

FUNCTIONS AND POINTERS

 

1. FUNCTIONS

 

A function, which can also be referred to as subroutine, procedure, subprogram or even method, carries out tasks defined by a sequence of statements called a statement block that need only be written once and called by a program as many times as needed to carry out the same task.

 

Functions may depend on variables passed to them, called arguments, and may pass results of a task on to the caller of the function, this is called the return value.

 

It is important to note that a function that exists in the global scope can also be called global function and a function that is defined inside a class is called a member function. (The term method is commonly used in other programming languages to refer to things like member functions, but this can lead to confusion in dealing with C++ which supports both virtual and non-virtual dispatch of member functions.)

 

 

2. Declarations

 

A function must be declared before being used, with a name to identify it, what type of value the function returns and the types of any arguments that are to be passed to it. Parameters must be named and declare what type of value it takes. Parameters should always be passed as const if their arguments are not modified. Usually functions performs actions, so the name should make clear what it does. By using verbs in function names and following other naming conventions programs can be read more naturally.

 

The next example we define a function named main that returns an integer value int and takes no parameters. The content of the function is called the body of the function. The word int is a keyword. C++ keywords are reserved words, i.e., cannot be used for any purpose other than what they are meant for. On the other hand main is not a keyword and you can use it in many places where a keyword cannot be used (though that is not recommended, as confusion could result).

 

int main()

{

 

// code return 0;

}

 

The inline keyword declares an inline function, the declaration is a (non-binding) request to the compiler that a particular function be subjected to in-line expansion; that is, it suggests that the compiler insert the complete body of the function in every context where that function is used and so it is used to avoid the overhead implied by making a CPU jump from one place in code to another and back again to execute a subroutine, as is done in naive implementations of subroutines.

 

inline swap( int& a, int& b) { int const tmp(b); b=a; a=tmp; }

 

When a function definition is included in a class/struct definition, it will be an implicit inline, the compiler will try to automatically inline that function. No inline keyword is necessary in this case; it is legal, but redundant, to add the inline keyword in that context, and good style is to omit it.

 

Example: struct length

 

{

 

explicit length(int metres) : m_metres(metres) {}

operator int&() { return m_metres; }

private:

int m_metres; };

 

Inlining can be an optimization, or a pessimization. It can increase code size (by duplicating the code for a function at multiple call sites) or can decrease it (if the code for the function, after optimization, is less than the size of the code needed to call a non-inlined function). It can increase speed (by allowing for more optimization and by avoiding jumps) or can decrease speed (by increasing code size and hence cache misses).

 

One important side-effect of inlining is that more code is then accessible to the optimizer. Marking a function as inline also has an effect on linking: multiple definitions of an inline function are permitted (so long as each is in a different translation unit) so long as they are

 

identical. This allows inline function definitions to appear in header files; defining non-inlined functions in header files is almost always an error (though function templates can also be defined in header files, and often are).

 

Mainstream C++ compilers like Microsoft Visual C++ and GCC support an option that lets the compilers automatically inline any suitable function, even those that are not marked as inline functions. A compiler is often in a better position than a human to decide whether a particular function should be inlined; in particular, the compiler may not be willing or able to inline many functions that the human asks it to.

 

Excessive use of inlined functions can greatly increase coupling/dependencies and compilation time, as well as making header files less useful as documentation of interfaces.

 

Normally when calling a function, a program will evaluate and store the arguments, and then call (or branch to) the function's code, and then the function will later return back to the caller. While function calls are fast (typically taking much less than a microsecond on modern processors), the overhead can sometimes be significant, particularly if the function is simple and is called many times.

 

One approach which can be a performance optimization in some situations is to use so-called inline functions. Marking a function as inline is a request (sometimes called a hint) to the compiler to consider replacing a call to the function by a copy of the code of that function.

 

The result is in some ways similar to the use of the #define macro, but as mentioned before, macros can lead to problems since they are not evaluated by the preprocessor. inline functions do not suffer from the same problems.

 

If the inlined function is large, this replacement process (known for obvious reasons as "inlining") can lead to "code bloat", leading to bigger (and hence usually slower) code. However, for small functions it can even reduce code size, particularly once a compiler's optimizer runs.

 

Note that the inlining process requires that the function's definition (including the code) must be available to the compiler. In particular, inline headers that are used from more than one source file must be completely defined within a header file (whereas with regular functions that would be an error).

 

The most common way to designate that a function is inline is by the use of the inline keyword. One must keep in mind that compilers can be configured to ignore the keyword and use their own optimizations.

 

Further considerations are given when dealing with inline member function, this will be covered on the Object-Oriented Programming

 

3. Parameters and arguments

 

The function declaration defines its parameters. A parameter is a variable which takes on the meaning of a corresponding argument passed in a call to a function.

 

An argument represents the value you supply to a function parameter when you call it. The calling code supplies the arguments when it calls the function.

 

The part of the function declaration that declares the expected parameters is called the parameter list and the part of function call that specifies the arguments is called the argument list. //Global functions declaration

 

int subtraction_function( int parameter1, int parameter2 ) { return ( parameter1 - parameter2 ); } //Call to the above function using 2 extra variables so the relation becomes more evident

 

int argument1 = 4; int argument2 = 3;

 

int result = subtraction_function( argument1, argument2 ); // will have the same result as

 

int result = subtraction_function( 4, 3 );

 

Many programmers use parameter and argument interchangeably, depending on context to distinguish the meaning. In practice, distinguishing between the two terms is usually unnecessary in order to use them correctly or communicate their use to other programmers. Alternatively, the equivalent terms formal parameter and actual parameter may be used instead of parameter and argument.

 

4. Parameters

 

We can define a function with no parameters, one parameter, or more than one, but to use a call to that function with arguments you must take into consideration what is defined. Empty parameter list

 

//Global functions with no parameters

void function() { /*...*/ }

 

//empty parameter declaration equivalent the use of void

void function( void ) { /*...*/ }

 

Multiple parameters

 

The syntax for declaring and invoking functions with multiple parameters can be a source of errors. When you write the function definition, you must declare the type of each and every parameter.

 

// Example - function using two int parameters by value

void printTime (int hour, int minute) {

 

std::cout << hour;

std::cout << ":";

std::cout << minute;

 

}

 

It might be tempting to write (int hour, minute), but that format is only legal for variable declarations, not for parameter declarations.

 

However, you do not have to declare the types of arguments when you call a function. (Indeed, it is an error to attempt to do so).

 

Example

 

int main ( void ) {

int hour = 11;

 

int minute = 59;

 

printTime( int hour, int minute ); // WRONG!

printTime( hour, minute ); // Right!

}

 

In this case, the compiler can tell the type of hour and minute by looking at their declarations. It is unnecessary and illegal to include the type when you pass them as arguments..

 

5. by pointer

 

A function may use pass by pointer when the object pointed to might not exist, that is, when you are giving either the address of a real object or NULL. Passing a pointer is not different to passing anything else. Its a parameter the same as any other. The characteristics of the pointer type is what makes it a worth distinguishing.

 

The passing of a pointer to a function is very similar to passing it as a reference. It is used to avoid the overhead of copying, and the slicing problem (since child classes have a bigger memory footprint that the parent) that can occur when passing base class objects by value. This is also the preferred method in C (for historical reasons), were passing by pointer signifies that wanted to modify the original variable. In C++ it is preferred to use references to pointers and guarantee that the function before dereferencing it, verifies the pointer for validity.

 

#include <iostream>

void MyFunc( int *x )

 

{

std::cout << *x << std::endl; // See next section for explanation

}

 

int main()

{

 

int i; MyFunc( &i );

return 0;

 

}

 

Since a reference is just an alias, it has exactly the same address as what it refers to, as in the following example:

 

#include <iostream>

void ComparePointers (int * a, int * b)

{

if (a == b)

 

std::cout<<"Pointers are the same!"<<std::endl; else

 

std::cout<<"Pointers are different!"<<std::endl;

}

 

int main()

{

 

int i, j; int& r = i;

 

ComparePointers(&i, &i); ComparePointers(&i, &j); ComparePointers(&i, &r); ComparePointers(&j, &r);

return 0;

 

}

 

In object-oriented programming, a friend function that is a "friend" of a given class is allowed access to private and protected data in that class that it would not normally be able to as if the data was public. Normally, a function that is defined outside of a class cannot access such information. Declaring a function a friend of a class allows this, in languages where the concept is supported.

 

A friend function is declared by the class that is granting access, explicitly stating what function from a class is allowed access. A similar concept is that of friend class.

 

Friends should be used with caution. Too many functions or external classes declared as friends of a class with protected or private data may lessen the value of encapsulation of separate classes in object-oriented programming and may indicate a problem in the overall architecture design. Generally though, friend functions are a good thing for encapsulation, as you can keep data of a class private from all except those who you explicitly state need it, but this does mean your classes will become tightly coupled.

 

6. Use cases

 

This approach may be used in friendly function when a function needs to access private data in objects from two different classes. This may be accomplished in two similar ways a function of global or namespace scope may be declared as friend of both classes   a member function of one class may be declared as friend of another one.

#include <iostream>

using namespace std;

 

class Foo; // Forward declaration of class Foo in order for example to compile. class Bar {

 

private: int a; public:

 

Bar(): a(0) {}

void show(Bar& x, Foo& y);

friend void show(Bar& x, Foo& y); // declaration of global friend

};

 

class Foo { private: int b; public:

 

Foo(): b(6) {}

friend void show(Bar& x, Foo& y); // declaration of global friend

friend void Bar::show(Bar& x, Foo& y); // declaration of friend from other class

};

 

//  Definition of a member function of Bar; this member is a friend of Foo void Bar::show(Bar& x, Foo& y) {

 

cout << "Show via function member of Bar" << endl; cout << "Bar::a = " << x.a << endl;

 

cout << "Foo::b = " << y.b << endl;

 

}

 

//  Friend for Bar and Foo, definition of global function

 

void show(Bar& x, Foo& y) {

 

cout << "Show via global function" << endl; cout << "Bar::a = " << x.a << endl;

 

cout << "Foo::b = " << y.b << endl;

}

 

int main() { Bar a; Foo b;

 

 

show(a,b);

a.show(a,b);

}

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail
Object Oriented Programming(OOP) : Overview : Functions and Pointers |


Privacy Policy, Terms and Conditions, DMCA Policy and Compliant

Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.