What are the Pointer-to-Member ->* and .* Operators in C++?

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-26 04:39:05

问题


Yes, I\'ve seen this question and this FAQ (wrong link) this FAQ, but I still don\'t understand what ->* and .* mean in C++.
Those pages provide information about the operators (such as overloading), but don\'t seem to explain well what they are.

What are ->* and .* in C++, and when do you need to use them as compared to -> and .?


回答1:


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




回答2:


EDIT: By the way, it gets weird for virtual member functions pointers.

For member variables:

struct Foo {
   int a;
   int b;
};


int main ()
{
    Foo foo;
    int (Foo :: * ptr);

    ptr = & Foo :: a;
    foo .*ptr = 123; // foo.a = 123;

    ptr = & Foo :: b;
    foo .*ptr = 234; // foo.b = 234;
}

Member functions are almost the same.

struct Foo {
   int a ();
   int b ();
};


int main ()
{
    Foo foo;
    int (Foo :: * ptr) ();

    ptr = & Foo :: a;
    (foo .*ptr) (); // foo.a ();

    ptr = & Foo :: b;
    (foo .*ptr) (); // foo.b ();
}



回答3:


In a nutshell: You use -> and . if you know what member you want to access. And you use ->* and .* if you don't know what member you want to access.

Example with a simple intrusive list

template<typename ItemType>
struct List {
  List(ItemType *head, ItemType * ItemType::*nextMemPointer)
  :m_head(head), m_nextMemPointer(nextMemPointer) { }

  void addHead(ItemType *item) {
    (item ->* m_nextMemPointer) = m_head;
    m_head = item;
  }

private:
  ItemType *m_head;

  // this stores the member pointer denoting the 
  // "next" pointer of an item
  ItemType * ItemType::*m_nextMemPointer;
};



回答4:


So called "pointers" to members in C++ are more like offsets, internally. You need both such a member "pointer", and an object, to reference the member in the object. But member "pointers" are used with pointer syntax, hence the name.

There are two ways you can have an object at hand: you have a reference to the object, or you have a pointer to the object.

For the reference, use .* to combine it with a member pointer, and for the pointer, use ->* to combine it with a member pointer.

However, as a rule, don't use member pointers if you can avoid it.

They obey pretty counter-intuitive rules, and they make it possible to circumvent protected access without any explicit casting, that is, inadvertently…

Cheers & hth.,




回答5:


You cannot dereference pointer to members as normal pointers — because member functions require this pointer, and you have to pass it somehow. So, you need to use these two operators, with object on one side, and pointer on another, e.g. (object.*ptr)().

Consider using function and bind (std:: or boost::, depending on whether you write C++03 or 0x) instead of those, though.




回答6:


When you have a normal pointer (to an object or a basic type), you would use * to dereference it:

int a;
int* b = a;
*b = 5;     // we use *b to dereference b, to access the thing it points to

Conceptually, we're doing the same thing with a member function pointer:

class SomeClass
{
   public:  void func() {}
};

// typedefs make function pointers much easier.
// this is a pointer to a member function of SomeClass, which takes no parameters and returns void
typedef void (SomeClass::*memfunc)();

memfunc myPointer = &SomeClass::func;

SomeClass foo;

// to call func(), we could do:
foo.func();

// to call func() using our pointer, we need to dereference the pointer:
foo.*myPointer();
// this is conceptually just:    foo  .  *myPointer  ();


// likewise with a pointer to the object itself:
SomeClass* p = new SomeClass;

// normal call func()
p->func();

// calling func() by dereferencing our pointer:
p->*myPointer();
// this is conceptually just:    p  ->  *myPointer  ();

I hope that helps explain the concept. We're effectively dereferencing our pointer to the member function. It's a little more complicated than that -- it's not an absolute pointer to a function in memory, but just an offset, which is applied to foo or p above. But conceptually, we're dereferencing it, much like we would dereference a normal object pointer.



来源:https://stackoverflow.com/questions/6586205/what-are-the-pointer-to-member-and-operators-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!