Ponteiros para membros
As declarações dos ponteiros para os membros são casos especiais de declarações do ponteiro. Elas são declaradas usando a seguinte sequência:
[storage-class-specifiers] [cv-qualifiers] type-specifiers [ms-modifier]
qualified-name ::* [cv-qualifiers] identifier
[= & qualified-name :: member-name];
O especificador de declaração:
Um especificador de classe de armazenamento opcional.
Especificadores opcionais const e/ou volatile.
O especificador de tipo: o nome de um tipo. Este é o tipo de membro a ser apontado, não a classe.
O declarador:
Um modificador opcional específico da Microsoft. Para obter mais informações, consulte Modificadores específicos da Microsoft.
O nome qualificado da classe que contém os membros a serem apontados. Consulte Nomes e nomes qualificados.
O operador ::.
O operador *.
Especificadores opcionais const e/ou volatile.
O identificador que nomeia o ponteiro para o membro.
Um inicializador opcional:
O operador =.
O operador &.
O nome qualificado da classe.
O operador ::.
O nome de um membro não estático da classe de tipo apropriado.
Como sempre, vários declaradores (e quaisquer inicializadores associados) são permitidos em uma única declaração.
Um ponteiro para um membro de uma classe é diferente de um ponteiro regular somente porque tem as informações do tipo para o tipo do membro e para a classe a qual o membro pertence. Um ponteiro normal (tem o endereço de) identifica somente um único objeto na memória. Um ponteiro para um membro de uma classe identifica esse membro em qualquer instância da classe. O exemplo a seguir declara uma classe, Window, e alguns ponteiros para os dados de membro.
// pointers_to_members1.cpp
class Window
{
public:
Window(); // Default constructor.
Window( int x1, int y1, // Constructor specifying
int x2, int y2 ); // window size.
bool SetCaption( const char *szTitle ); // Set window caption.
const char *GetCaption(); // Get window caption.
char *szWinCaption; // Window caption.
};
// Declare a pointer to the data member szWinCaption.
char * Window::* pwCaption = &Window::szWinCaption;
int main()
{
}
No exemplo anterior, pwCaption é um ponteiro para qualquer membro da classe Window que tem o tipo char*. O tipo de pwCaption é char * Window::*. O fragmento de código a seguir declara ponteiros para as funções de membro SetCaption e GetCaption.
const char * (Window::*pfnwGC)() = &Window::GetCaption;
bool (Window::*pfnwSC)( const char * ) = &Window::SetCaption;
Os ponteiros pfnwGC e pfnwSC apontam para GetCaption e SetCaption da classe Window, respectivamente. O código copia informações para a legenda da janela diretamente usando o ponteiro para o membro pwCaption:
Window wMainWindow;
Window *pwChildWindow = new Window;
char *szUntitled = "Untitled - ";
int cUntitledLen = strlen( szUntitled );
strcpy_s( wMainWindow.*pwCaption, cUntitledLen, szUntitled );
(wMainWindow.*pwCaption)[cUntitledLen - 1] = '1'; //same as
//wMainWindow.SzWinCaption [cUntitledLen - 1] = '1';
strcpy_s( pwChildWindow->*pwCaption, cUntitledLen, szUntitled );
(pwChildWindow->*pwCaption)[cUntitledLen - 1] = '2'; //same as //pwChildWindow->szWinCaption[cUntitledLen - 1] = '2';
A diferença entre os operadores .* e –>* (operadores de ponteiro a membro) é que o operador .* seleciona os membros com um objeto ou uma referência de objeto, enquanto o operador –>* seleciona membros por meio de um ponteiro. (Para obter mais informações sobre esses operadores, consulte Expressões com operadores de ponteiro à membro.)
O resultado dos operadores de ponteiro à membro é o tipo de membro — nesse caso, char *.
O fragmento de código a seguir invoca as funções do membro GetCaption e SetCaption usando ponteiros para os membros:
// Allocate a buffer.
enum {
sizeOfBuffer = 100
};
char szCaptionBase[sizeOfBuffer];
// Copy the main window caption into the buffer
// and append " [View 1]".
strcpy_s( szCaptionBase, sizeOfBuffer, (wMainWindow.*pfnwGC)() );
strcat_s( szCaptionBase, sizeOfBuffer, " [View 1]" );
// Set the child window's caption.
(pwChildWindow->*pfnwSC)( szCaptionBase );