Pointers to members
Syntax#
-
Assuming a class named Class…
- type *ptr = &Class::member; // Point to static members only
- type Class::*ptr = &Class::member; // Point to non-static Class members
-
For pointers to non-static class members, given the following two definitions:
- Class instance;
- Class *p = &instance;
-
Pointers to Class member variables
- ptr = &Class::i; // Point to variable i within every Class
- instance.*ptr = 1; // Access instance’s i
- p->*ptr = 1; // Access p’s i
-
Pointers to Class member functions
- ptr = &Class::F; // Point to function ‘F’ within every Class
- (instance.*ptr)(5); // Call instance’s F
- (p->*ptr)(6); // Call p’s F
Pointers to static member functions
A static
member function is just like an ordinary C/C++ function, except with scope:
- It is inside a
class
, so it needs its name decorated with the class name; - It has accessibility, with
public
,protected
orprivate
.
So, if you have access to the static
member function and decorate it correctly, then you can point to the function like any normal function outside a class
:
typedef int Fn(int); // Fn is a type-of function that accepts an int and returns an int
// Note that MyFn() is of type 'Fn'
int MyFn(int i) { return 2*i; }
class Class {
public:
// Note that Static() is of type 'Fn'
static int Static(int i) { return 3*i; }
}; // Class
int main() {
Fn *fn; // fn is a pointer to a type-of Fn
fn = &MyFn; // Point to one function
fn(3); // Call it
fn = &Class::Static; // Point to the other function
fn(4); // Call it
} // main()
Pointers to member functions
To access a member function of a class, you need to have a “handle” to the particular instance, as either the instance itself, or a pointer or reference to it. Given a class instance, you can point to various of its members with a pointer-to-member, IF you get the syntax correct! Of course, the pointer has to be declared to be of the same type as what you are pointing to…
typedef int Fn(int); // Fn is a type-of function that accepts an int and returns an int
class Class {
public:
// Note that A() is of type 'Fn'
int A(int a) { return 2*a; }
// Note that B() is of type 'Fn'
int B(int b) { return 3*b; }
}; // Class
int main() {
Class c; // Need a Class instance to play with
Class *p = &c; // Need a Class pointer to play with
Fn Class::*fn; // fn is a pointer to a type-of Fn within Class
fn = &Class::A; // fn now points to A within any Class
(c.*fn)(5); // Pass 5 to c's function A (via fn)
fn = &Class::B; // fn now points to B within any Class
(p->*fn)(6); // Pass 6 to c's (via p) function B (via fn)
} // main()
Unlike pointers to member variables (in the previous example), the association between the class instance and the member pointer need to be bound tightly together with parentheses, which looks a little strange (as though the .*
and ->*
aren’t strange enough!)
Pointers to member variables
To access a member of a class
, you need to have a “handle” to the particular instance, as either the instance itself, or a pointer or reference to it. Given a class
instance, you can point to various of its members with a pointer-to-member, IF you get the syntax correct! Of course, the pointer has to be declared to be of the same type as what you are pointing to…
class Class {
public:
int x, y, z;
char m, n, o;
}; // Class
int x; // Global variable
int main() {
Class c; // Need a Class instance to play with
Class *p = &c; // Need a Class pointer to play with
int *p_i; // Pointer to an int
p_i = &x; // Now pointing to x
p_i = &c.x; // Now pointing to c's x
int Class::*p_C_i; // Pointer to an int within Class
p_C_i = &Class::x; // Point to x within any Class
int i = c.*p_C_i; // Use p_c_i to fetch x from c's instance
p_C_i = &Class::y; // Point to y within any Class
i = c.*p_C_i; // Use p_c_i to fetch y from c's instance
p_C_i = &Class::m; // ERROR! m is a char, not an int!
char Class::*p_C_c = &Class::m; // That's better...
} // main()
The syntax of pointer-to-member requires some extra syntactic elements:
- To define the type of the pointer, you need to mention the base type, as well as the fact that it is inside a class:
int Class::*ptr;
. - If you have a class or reference and want to use it with a pointer-to-member, you need to use the
.*
operator (akin to the.
operator). - If you have a pointer to a class and want to use it with a pointer-to-member, you need to use the
->*
operator (akin to the->
operator).
Pointers to static member variables
A static
member variable is just like an ordinary C/C++ variable, except with scope:
- It is inside a
class
, so it needs its name decorated with the class name; - It has accessibility, with
public
,protected
orprivate
.
So, if you have access to the static
member variable and decorate it correctly, then you can point to the variable like any normal variable outside a class
:
class Class {
public:
static int i;
}; // Class
int Class::i = 1; // Define the value of i (and where it's stored!)
int j = 2; // Just another global variable
int main() {
int k = 3; // Local variable
int *p;
p = &k; // Point to k
*p = 2; // Modify it
p = &j; // Point to j
*p = 3; // Modify it
p = &Class::i; // Point to Class::i
*p = 4; // Modify it
} // main()