85 votes

Quels sont le Pointeur de Membre ->* et .* Les opérateurs en C++?

Oui, j'ai vu cette question et cette FAQ (mauvais lien) cette FAQ, mais j'ai encore ne comprennent pas ce qu' ->* et .* moyenne de en C++.
Ces pages fournissent des informations sur les opérateurs (tels que la surcharge), mais ne semblent pas bien expliquer ce qu'ils sont.

Quelles sont ->* et .* en C++, et quand avez-vous besoin de les utiliser comme comparé à d' -> et .?

97voto

Armen Tsirunyan Points 59548

J'espère que cet exemple sera de clarifier les choses pour vous

//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();

Maintenant, vous ne pouvez pas utiliser x.somePointer()ou px->somePointer() car il n'est pas membre de la classe X. Pour que la fonction de membre du pointeur de la syntaxe d'appel est utilisé... juste essayer quelques exemples vous-même ,vous allez en prendre l'habitude

26voto

spraff Points 10492

EDIT: En passant, c'est bizarre pour le membre virtuel des pointeurs de fonctions.

Pour les variables membres:

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;
}

Les fonctions de membres sont presque les mêmes.

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 ();
}

15voto

En un mot: Vous utilisez -> et . si vous savez ce membre auquel vous souhaitez accéder. Et vous utilisez ->* et .* si vous n'avez pas savoir ce membre auquel vous souhaitez accéder.

Exemple avec un simple intrusive liste

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;
};

8voto

Soi-disant "pointeurs" pour les membres en C++ sont plus comme des décalages, en interne. Vous avez besoin d'un membre de "pointeur", et un objet, pour faire référence au membre dans l'objet. Mais membre de "pointeurs" sont utilisés avec le pointeur de la syntaxe, d'où le nom.

Il ya deux façons vous pouvez avoir un objet à portée de main: vous avez une référence à l'objet, ou si vous avez un pointeur vers l'objet.

Pour la référence, utilisez .* de la combiner avec un pointeur de membre, et pour le pointeur, utilisation ->* de la combiner avec un pointeur de membre.

Cependant, en règle générale, ne pas utiliser de pointeurs si vous pouvez l'éviter.

Ils obéissent assez contre-intuitive, les règles, et elles permettent de contourner protected d'accès sans aucun explicite de la coulée, qui est, par inadvertance...

Cheers & hth.,

5voto

Cat Plus Plus Points 53385

Vous ne pouvez pas déréférencement de pointeur comme normal pointeurs - en raison des fonctions membres exigent this pointeur, et vous devez passer en quelque sorte. Donc, vous avez besoin d'utiliser ces deux opérateurs, avec l'objet sur un côté, et un pointeur sur une autre, par exemple, (object.*ptr)().

Envisager l'utilisation d' function et bind (std:: ou boost::, selon que vous écrivez en C++03 ou 0x) à la place de ceux-ci, cependant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X