What Are the Pointer-To-Member Operators -≫* and .* in C++

What are the pointer-to-member operators - * and .* in C++?

I hope this example will clear things for you

//we have a class
struct X
{
void f() {}
void g() {}
};

typedef void (X::*pointer)();
//ok, let's take a pointer and assign f to it.
pointer somePointer = &X::f;
//now I want to call somePointer. But for that, I need an object
X x;
//now I call the member function on x like this
(x.*somePointer)(); //will call x.f()
//now, suppose x is not an object but a pointer to object
X* px = new X;
//I want to call the memfun pointer on px. I use ->*
(px ->* somePointer)(); //will call px->f();

Now, you can't use x.somePointer(), or px->somePointer() because there is no such member in class X. For that the special member function pointer call syntax is used... just try a few examples yourself ,you'll get used to it

use of pointer-to-member operators?

Pointers-to-members are a special gadget in C++ that tell only tell you about a which member of a class you want without pertaining to any object. You need to combine a pointer-to-member with an object instance in order to obtain an actual member, whether it be a data or a function member.

Think of pointers-to-member as "offsets". Also, remember that pointers-to-member are not pointers!

We can rewrite your code to make it a bit clearer:

struct Foo
{
int a;
int b;
double f(int, int);
double g(int, int);
};

int main()
{
int Foo::*ptm = &Foo::a;
double (Foo::*ptmf)(int, int) = &Foo::f;

Foo x, y, z;

int numbers[] = { x.*ptm, y.*ptm, z.*ptm }; // array of Foo::a's

ptm = &Foo::b; // reseat the PTM

int more[] = { x.*ptm, y.*ptm, z.*ptm }; // array of Foo::b's


double yetmore[] = { (x.*ptmf)(1,2), (y.*ptmf)(1,2) };

ptmf = &Foo::g;

double evenmore[] = { (x.*ptmf)(1,2), (y.*ptmf)(1,2) };
}

Note how we're using the pointers-to-member to refer only to the class member, and we can use that to get the same relative class member out of different objects.

(By contrast, we can also form a real pointer to an actual object member: int * p = &x.a;. That's because the member-int is actually an integer. But we cannot do anything analogous for member functions, because member functions are not functions (e.g. you cannot call them).)

Make sure you understand the difference between classes and objects, and this should become very clear!

Address operator with pointer to member function

It is because now that function is defined inside the class. Pointer to member function holds the "relative address" of where the function is in the class layout and so you have to access it that way.

In case of static, it has no this pointer and it behaves like a global function and so, you can access it like normal function pointer.

how to use pointer to operator in member functions?

Here is a toy example using operator ! and a member pointer to it, looks like VC++ 10 was ok with it:

class Test
{
public:
bool operator !() {return true;};
};

typedef bool (Test::* memfunptr)();

int main(){

Test tt;
memfunptr mf = &Test::operator!;

bool res = (tt.*mf)();

return 0;
}

So, try something along the lines of:

tArray_t intArray;
(intArray.*insert)(&((intArray.*op)(1)));

(Not sure what your actual definitions of intArray and insert are, so I'm guessing here that intArray is an instance and insert is another member ptr)

What is name of this operator - *?

It's called "pointer to member of pointer" and is one of the "pointer to member" type operators (in addition to .*, "pointer to member of object").

You can use it when you take the address of a member variable or function of a class, then you want to access that variable or call that function on an instance of that class, given a pointer to the instance (like a vanilla data or function pointer, but to a class member).

Here is an example using function pointers:

#include <cstdio>
using namespace std;

class Example {
public:
Example (int value) : value_(value) { }
void printa (const char *s) { printf("A %i %s\n", value_, s); }
void printb (const char *s) { printf("B %i %s\n", value_, s); }
private:
int value_;
};

// print_member_ptr can point to any member of Example that
// takes const char * and returns void.
typedef void (Example::* print_member_ptr) (const char *);

int main () {

print_member_ptr ptr;
Example x(1), y(2), *p = new Example(3), *q = new Example(4);

ptr = &Example::printa;
// .*ptr and ->*ptr will call printa
(x.*ptr)("hello");
(y.*ptr)("hello");
(p->*ptr)("hello");
(q->*ptr)("hello");

ptr = &Example::printb;
// now .*ptr and ->*ptr will call printb
(x.*ptr)("again");
(y.*ptr)("again");
(p->*ptr)("again");
(q->*ptr)("again");

}

The output is:

A 1 hello
A 2 hello
A 3 hello
A 4 hello
B 1 again
B 2 again
B 3 again
B 4 again

See http://en.cppreference.com/w/cpp/language/operator_member_access for more details.

c++ pointers to operators

No, you can't do this. The class type is a part of the type of the operator member function.

The type of A::operator()() is different from the type of B::operator()(). The former is of type int (A::*)() while the latter is of type int (B::*)(). Those types are entirely unrelated.

The closest you can get is by using something like the C++0x polymorphic function wrapper function (found in C++0x, C++ TR1, and Boost) and by using bind to bind the member function pointer to a class instance:

std::function<int()> _p;

A a;
_p = std::bind(&A::operator(), a);
std::cout << _p();

B b;
_p = std::bind(&B::operator(), b);
std::cout << _p();

Bind pointer to member operators in C++

A PMF (pointer to member function) is like a normal (static) function pointer, except, because non-static member functions require the this object to be specified, the PMF invocation syntax (.* or ->*) allow the this object to be specified (on the left-hand side).

Here's an example of PMFs in use (note the "magic" line with the .* operator being used: (lhs.*opit->second)(...), and the syntax for creating a PMF, &class::func):

#include <complex>
#include <iostream>
#include <map>
#include <stack>
#include <stdexcept>
#include <string>

namespace {
using std::cin; using std::complex; using std::cout;
using std::invalid_argument; using std::map; using std::stack;
using std::string; using std::underflow_error;

typedef complex<double> complexd;
typedef complexd& (complexd::*complexd_pmf)(complexd const&);
typedef map<char, complexd_pmf> opmap;

template <typename T>
typename T::reference top(T& st) {
if (st.empty())
throw underflow_error("Empty stack");
return st.top();
}
}

int
main()
{
opmap const ops{{'+', &complexd::operator+=},
{'-', &complexd::operator-=},
{'*', &complexd::operator*=},
{'/', &complexd::operator/=}};

char op;
complexd val;
stack<complexd> st;

while (cin >> op) {
opmap::const_iterator opit(ops.find(op));
if (opit != ops.end()) {
complexd rhs(top(st));
st.pop();
// For example of ->* syntax:
complexd& lhs(top(st)); // complexd* lhs(&top(st));
(lhs.*opit->second)(rhs); // (lhs->*opit->second)(rhs);
cout << lhs << '\n'; // cout << *lhs << '\n';
} else if (cin.unget() && cin >> val) {
st.push(val);
} else {
throw invalid_argument(string("Unknown operator ") += op);
}
}
}

[Download]

It's a simple RPN calculator using complex numbers instead of real numbers (mostly because std::complex is a class type with overloaded operators). I've tested this with clang; your mileage may vary with other platforms.

Input should be of the form (0,1). Spaces are optional, but can be added for readability.

Pointer to class data member ::*

It's a "pointer to member" - the following code illustrates its use:

#include <iostream>
using namespace std;

class Car
{
public:
int speed;
};

int main()
{
int Car::*pSpeed = &Car::speed;

Car c1;
c1.speed = 1; // direct access
cout << "speed is " << c1.speed << endl;
c1.*pSpeed = 2; // access via pointer to member
cout << "speed is " << c1.speed << endl;
return 0;
}

As to why you would want to do that, well it gives you another level of indirection that can solve some tricky problems. But to be honest, I've never had to use them in my own code.

Edit: I can't think off-hand of a convincing use for pointers to member data. Pointer to member functions can be used in pluggable architectures, but once again producing an example in a small space defeats me. The following is my best (untested) try - an Apply function that would do some pre &post processing before applying a user-selected member function to an object:

void Apply( SomeClass * c, void (SomeClass::*func)() ) {
// do hefty pre-call processing
(c->*func)(); // call user specified function
// do hefty post-call processing
}

The parentheses around c->*func are necessary because the ->* operator has lower precedence than the function call operator.



Related Topics



Leave a reply



Submit