Каковы операторы Pointer-to-Member -> * и. * В C ++?

Да, я видел этот вопрос и этот FAQ (неправильная ссылка) этот FAQ , но я до сих пор не понимаю, что ->* и .* Означает в C ++.
Эти страницы предоставляют информацию об операторах (например, перегрузку), но, похоже, не объясняют, каковы они.

Что такое ->* и .* В C ++, и когда вам нужно использовать их по сравнению с -> и . ?

Я надеюсь, что этот пример очистит вас от вас

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

Теперь вы не можете использовать x.somePointer() или px->somePointer() потому что в classе X нет такого члена. Для этого используется специальный синтаксис вызова указателя функций-членов … просто попробуйте несколько примеров самостоятельно , вы привыкнете к этому

EDIT: Кстати, он становится странным для виртуальных указателей функций .

Для переменных-членов:

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

Функции членов почти одинаковы.

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

Вкратце: вы используете -> и . если вы знаете, к кому вы хотите получить доступ. И вы используете ->* и .* Если вы не знаете, к кому вы хотите получить доступ.

Пример с простым навязчивым списком

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

Так называемые «указатели» для членов на C ++ больше похожи на смещения внутри. Вам нужен и такой «указатель» члена, и объект, чтобы ссылаться на элемент в объекте. Но члены «указатели» используются с синтаксисом указателя, отсюда и название.

Существует два способа иметь объект под рукой: у вас есть ссылка на объект или указатель на объект.

Для справки используйте .* Чтобы объединить его с указателем-членом, а для указателя используйте ->* чтобы объединить его с указателем-членом.

Однако, как правило, не используйте указатели-члены, если вы можете избежать этого.

Они подчиняются довольно противоречивым правилам, и они позволяют обойти protected доступ без какого-либо явного литья, то есть непреднамеренно …

Cheers & hth.,

Если у вас нормальный указатель (на объект или базовый тип), вы должны использовать * для разыменования:

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

Понятно, что мы делаем то же самое с указателем на функцию-член:

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

Надеюсь, это поможет объяснить концепцию. Мы фактически разыскиваем наш указатель на функцию-член. Это немного сложнее, чем это – это не абсолютный указатель на функцию в памяти, а только смещение, которое применяется к foo или p выше. Но концептуально мы разыгрываем его, так же, как мы бы разыменовали обычный указатель объекта.

Вы не можете разыскивать указатель на члены как обычные указатели, потому что функции-члены требуют this указателя, и вам нужно каким-то образом передать его. Таким образом, вам нужно использовать эти два оператора, с объектом с одной стороны, и указатель на другой, например (object.*ptr)() .

Однако рассмотрим возможность использования function и bind ( std:: или boost:: , в зависимости от того, пишете ли вы C ++ 03 или 0x).

  • Оператор Dot (".") И стрелка ("->") используют в C против Objective-C
  • Является ли указатель «один-на-конец» типа не-массива допустимым понятием в C ++?
  • Используя оператор равенства == для сравнения двух строк для равенства в C
  • Как избежать утечек памяти при использовании вектора указателей на динамически выделенные объекты в C ++?
  • как отображать изображения, сохраненные в папке sdcard в android
  • Как использовать iterator?
  • Неинициализированные указатели в коде
  • Как связаны iteratorы и указатели?
  • выделить матрицу в C
  • Почему в C ++ не существует ссылки на член?
  • Давайте будем гением компьютера.