Операторы доступа по указателю на член: .*
и ->*
Операторы доступа указателя на член, .*
и ->*
, предназначены для разыменования указателя на член в сочетании с объектом и указателем на объект соответственно. Это описание применимо как к указателям на данные-члены, так и к указателям на функции-члены.
Например, рассмотрим класс Foo
:
struct Foo {
int i;
void f();
};
Если вы объявляете указатель члена iPtr
на элемент данных int
элемента Foo
:
int Foo::* iPtr;
Вы можете инициализировать этот указатель члена iPtr
так, чтобы он указывал на член Foo::i
:
iPtr = &Foo::i;
Чтобы разыменовать этот указатель, вам нужно использовать его вместе с объектом Foo
.
Рассмотрим теперь объект foo
и указатель на объект fooPtr
:
Foo foo;
Foo* fooPtr = &foo;
Затем вы можете разыменовать iPtr
в сочетании с foo
или fooPtr
:
foo.*iPtr = 0;
fooPtr->*iPtr = 0;
Аналогичным образом вы можете использовать .*
и ->*
с указателями на функции-члены. Однако обратите внимание, что вам нужно будет заключить их в круглые скобки, поскольку оператор вызова функции, то есть ()
, имеет более высокий приоритет, чем .*
и ->*
:
void (Foo::*memFuncPtr)() = &Foo::f;
(foo.*memFuncPtr)();
(fooPtr->*memFuncPtr)();
В заключение: вам нужен объект для разыменования указателя на член, и какой из них вы используете, .*
или ->*
для разыменования указателя на член, зависит от того, предоставляется ли этот необходимый объект напрямую или через указатель объекта.
C++17 — вместо этого используется std::invoke()
Использование обоих операторов можно заменить, начиная с C++17, на std::invoke
a> шаблон функции. std::invoke
обеспечивает унифицированный способ разыменования указателей на элементы независимо от того, используете ли вы их в сочетании с объектом или указателем объекта, а также независимо от того, используется ли указатель на элемент соответствует указателю на член данных или указателю на функцию-член:
// dereference a pointer to a data member
std::invoke(iPtr, foo) = 0; // with an object
std::invoke(iPtr, fooPtr) = 0; // with an object pointer
// dereference a pointer to a member function
std::invoke(memFuncPtr, foo); // with an object
std::invoke(memFuncPtr, fooPtr); // with an object pointer
Этот унифицированный синтаксис соответствует обычному синтаксису вызова функций и может упростить написание универсального кода.
person
眠りネロク
schedule
19.08.2020