Что такое указатель на элемент - > * и.* Операторы в C++?
Да, я видел этот вопрос и этот FAQ (неправильная ссылка) этот FAQ, а я еще не понимаю, что ->*
и .*
значит в C++.
Эти страницы предоставляют информацию о операторы (например, перегрузка), но, похоже, не очень хорошо объясняют, что они are.
каковы ->*
и .*
в C++, и когда вам нужно использовать их по сравнению с ->
и .
?
6 ответов:
Я надеюсь, что этот пример поможет для вас
//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();
Теперь, вы не можете использовать
x.somePointer()
илиpx->somePointer()
потому что нет такого члена в классе 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<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; };
так называемые "указатели" на Члены в 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) вместо них.