Prayagasoft - web designer India, Ecommerce developer india, Ecommerce design

Pointers to Members and Functions

POINTERS TO MEMBERS

In ANSI C, function pointers are used like this:

#include <stdio.h> void f(int i) { printf("%d\n", i); } typedef void (*fp)(int); void main() { fp p = &f; (*p)(37); /* these are equivalent */ p(37); }

and are employed in a variety of ways, for example to specify a comparison function to a library function like qsort().

In C++, pointers can be similarly used, but there are a couple of quirks to consider. We will discuss two of them in this section, and another one in the next section.

The first point to mention is that C++ has C-style functions in it, but also has other types of functions, notably member functions. For example:

class A { public: void f(int); };

In this example, A::f(int) is a member function. That is, it operates on object instances of class A, and the function itself has a "this" pointer that points at the instance in question.

Because C++ is a strongly typed language, it is desirable that a pointer to a member function be treated differently than a pointer to a C-style function, and that a pointer to a function member of class A be distinguished from a pointer to a member of class B. To do this, we can say:

#include <iostream.h> class A { public: void f(int i) {cout << "value is: " << i << "\n";} }; typedef void (A::*pmfA)(int); pmfA x = &A::f; void main() { A a; A* p = &a; (p->*x)(37); }

Note the notation for actually calling the member function.

It is not possible to intermix such a type with other pointer types, so for example:

void f(int) {} pmfA x = &f;

is invalid.

A static member function, as in:

class A { public: static void g(int); }; typedef void (*fp)(int); fp p = &A::g;

is treated like a C-style function. A static function has no "this" pointer and does not operate on actual object instances.

Pointers to members are typically implemented just like C function pointers, but there is an issue with their implementation in cases where inheritance is used. In such a case, you have to worry about computing offsets of subobjects, and so on, when calling a member function, and for this purpose a runtime structure similar to a virtual table used for virtual functions is used.

It's also possible to have pointers to data members of a class, with the pointer representing an offset into a class instance. For example:

#include <iostream.h> class A { public: int x; }; typedef int A::*piA; piA x = &A::x; void main() { A a; A* p = &a; a.x = 37; cout << "value is: " << p->*x << "\n"; }

Note that saying "&A::x" does not take the address of an actual data member in an instance of A, but rather computes a generic offset that can be applied to any instance.

A NEW ANGLE ON FUNCTION POINTERS

The discussion on function pointers in this issue overlooks one key angle that has fairly recently been introduced into the language. This involves distinguishing between C and C++ pointers. A C-style pointer in C++, that is, one that does not point to a member function, is used just like a function pointer in C. But according to the standard (section 7.5), such a pointer in fact has a different type.

For example, consider:

extern "C" typedef void (*fp1)(int); extern "C++" typedef void (*fp2)(int); extern "C" void f(int);

fp1 and fp2 are not the same type, and saying:

fp2 p = &f;

to initialize p to the f(int) declared in the 'extern "C"' will not work.

It is possible to overload functions on this basis, so that for example:

extern "C" void f(void (*)(int)); extern "C++" void f(void (*)(int));

is legal, with the appropriate f() called based on the function pointer type passed to it. The function pointer parameter types in this example are not identical; the first is a pointer to a C function, the second a pointer to a C++ one.

 

India seo freelance web designer India web development ecommerce website developer India
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100