开发者

Esoteric C++ operators

What is the purpose of the following esoteric C++ operators?

Pointer to member

::*

Bind pointer to member by pointer

->*

Bind pointer to member by reference开发者_如何转开发

.*

(reference)


A pointer to a member allows you to have a pointer that is relative to a specific class.

So, let's say you have a contact class with multiple phone numbers.

class contact
{
    phonenumber office;
    phonenumber home;
    phonenumber cell;
};

The idea is if you have an algorithm that needs to use a phone number but the decision of which phone number should be done outside the algorithm, pointers to member solve the problem:

void robocall(phonenumber contact::*number, ...);

Now the caller of robocall can decide which type of phonenumber to use:

robocall(&contact::home, ...);    // call home numbers
robocall(&contact::office, ...);  // call office number

.* and ->* come into play once you have a pointer. So inside robocall, you would do:

contact c = ...;
c.*number;    // gets the appropriate phone number of the object

or:

contact *pc = ...;
pc->*number;


There's no such operator as ::* and there's never been. I don't know where you got it.

As for ->* and .* - these are dereference operators for pointers of pointer-to-member type.

struct S {
  int i;
};

int main() {
  int S::*pi = &S::i; // pointer of pointer-to-member type

  S s;
  S* ps = &s;

  s.*pi = 0; // operator `.*` used
  assert(s.i == 0);

  ps->*pi = 1; // operator `->*` used
  assert(s.i == 1);
}

As for what pointers-to-members are... what does your favorite C++ book say on the subject?


They relate to pointers-to-members and pointers-to-member-functions.

struct Foo {
    int a() { return 1; }
    int b() { return 2; }
    int c;
};

int main() {
    Foo f;
    f.c = 3;

    typedef int (Foo::*member_fn)(); // pointer-to-member-function
    typedef int (Foo::*data_member); // pointer-to-member

    member_fn mf = &Foo::a;
    (f.*mf)(); // calls the member function pointed to by mf. returns 1
    mf = &Foo::b;
    (f.*mf)(); // This time, returns 2, since mf points to b
    Foo *fp = &f;
    (fp->*mf)(); // same thing, via pointer to f instead of object/reference f.

    data_member dm = &Foo::c;
    f.*dm; // is 3
    f.*dm = 5;
    f.c;  // is now 5.

    Foo f2; // another instance
    f2.c = 12;
    f2.*dm;  // is 12. Same pointer-to-member, different object.
}

Although it might look like one, ::* isn't an operator. It's the :: operator and the * operator type modifier next to each other. To prove this without resorting to reading the standard, try adding spaces: :: * compiles, . * doesn't, neither does -> *.

As for what they're actually useful for - same principle as function pointers. You wouldn't use them as I have above, in a situation where you could just call the function by name, but you can pass them as parameters or return them from functions, store them, or select one of several based on complicated logic.

If it helps, I believe the syntax is chosen so that although .* is an indivisible single operator, you can imagine that *dm "means" c, the member pointed to by dm. So if dm points to c, then f.*dm is the same as f.c.


Check out the C++ FAQ Lite's section on pointers to member functions. Search for the specific "operators" you're talking about (in most browsers, Ctrl-F opens a Find/Search dialog that allows you to search for text in the Web page), and it should help you to understand things better.


An oversimplified answer - these operators allow to call member functions as 'regular' functions (at least it looks the same from the end user's perspective) . Real world example - they are used a lot in a various callback implementations.


These allow you to have pointers to member functions (and member variables) that are tied to a particular instance of the class.

Pointers to member functions can be useful for things like lightweight implementations of the state pattern. Generally, any time you want to vary the behavior of an object over time without resorting to switching out the entire object, you can consider the use of pointers to member functions.

Pointers to member variables can be used if you want to, e.g., implement a generic algorithm to search an array of structs for an entry that has a particular value for a given field.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜