Wskaźniki do elementów członkowskich
Deklaracje wskaźników do składowych są specjalnymi przypadkami deklaracji wskaźnika. Są one deklarowane przy użyciu następującej sekwencji:
specyfikatory klasy magazynu optcv-kwalifikatoryopt-specyfikatortypu ms-modifieroptkwalifikowanej nazwy
::*
cv-kwalifikatoryoptidentyfikatorpm-initializeropt opt;
Specyfikator deklaracji:
Opcjonalny specyfikator klasy magazynu.
Opcjonalne
const
ivolatile
specyfikatory.Specyfikator typu: nazwa typu. Jest to typ elementu członkowskiego do wskazywania, a nie klasy.
Deklarator:
Opcjonalny modyfikator specyficzny dla firmy Microsoft. Aby uzyskać więcej informacji, zobacz Modyfikatory specyficzne dla firmy Microsoft.
Kwalifikowana nazwa klasy zawierającej elementy członkowskie do wskazywania.
Operator
::
.Operator
*
.Opcjonalne
const
ivolatile
specyfikatory.Identyfikator nazewnictwa wskaźnika do elementu członkowskiego.
Opcjonalny inicjator wskaźnika do elementu członkowskiego:
Operator
=
.Operator
&
.Kwalifikowana nazwa klasy.
Operator
::
.Nazwa niestacjonanej składowej klasy odpowiedniego typu.
Tak jak zawsze, wiele deklaratorów (i wszystkich skojarzonych inicjatorów) jest dozwolonych w jednej deklaracji. Wskaźnik do składowej może nie wskazywać statycznej składowej klasy, składowej typu odwołania lub void
.
Wskaźnik do składowej klasy różni się od normalnego wskaźnika: ma zarówno informacje o typie elementu członkowskiego, jak i dla klasy, do której należy składowa. Normalny wskaźnik identyfikuje (ma adres) tylko jeden obiekt w pamięci. Wskaźnik do składowej klasy identyfikuje ten element członkowski w dowolnym wystąpieniu klasy. Poniższy przykład deklaruje klasę , Window
i niektóre wskaźniki do danych składowych.
// 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()
{
}
W poprzednim przykładzie pwCaption
jest wskaźnikiem do dowolnej składowej klasy Window
typu char*
. Typ to pwCaption
char * Window::*
. Następny fragment kodu deklaruje wskaźniki do funkcji składowych SetCaption
i GetCaption
.
const char * (Window::* pfnwGC)() = &Window::GetCaption;
bool (Window::* pfnwSC)( const char * ) = &Window::SetCaption;
pfnwGC
Wskaźniki i pfnwSC
wskazują GetCaption
odpowiednio i SetCaption
klasęWindow
. Kod kopiuje informacje do okna podpis bezpośrednio przy użyciu wskaźnika do elementu członkowskiego 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';
Różnica między operatorami .*
i ->*
(operatorami wskaźnika do składowych) polega na tym, że .*
operator wybiera elementy członkowskie, biorąc pod uwagę odwołanie do obiektu lub obiektu, podczas gdy ->*
operator wybiera elementy członkowskie za pomocą wskaźnika. Aby uzyskać więcej informacji na temat tych operatorów, zobacz Wyrażenia z operatorami wskaźników do składowych.
Wynikiem operatorów wskaźnika do elementu członkowskiego jest typ elementu członkowskiego. W tym przypadku jest to char *
.
Poniższy fragment kodu wywołuje funkcje GetCaption
składowe i SetCaption
używa wskaźników do elementów członkowskich:
// 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 );
Ograniczenia dotyczące wskaźników do elementów członkowskich
Adres statycznego elementu członkowskiego nie jest wskaźnikiem do elementu członkowskiego. Jest to zwykły wskaźnik do jednego wystąpienia statycznego elementu członkowskiego. Istnieje tylko jedno wystąpienie statycznego elementu członkowskiego dla wszystkich obiektów danej klasy. Oznacza to, że można użyć zwykłych operatorów adres-of (&) i dereference (*).
Wskaźniki do elementów członkowskich i funkcji wirtualnych
Wywoływanie funkcji wirtualnej za pośrednictwem funkcji wskaźnik-składowa działa tak, jakby funkcja została wywołana bezpośrednio. Poprawna funkcja jest sprawdzana w tabeli wirtualnej i wywoływana.
Kluczem do funkcji wirtualnych działa, jak zawsze, jest wywoływanie ich za pośrednictwem wskaźnika do klasy bazowej. (Aby uzyskać więcej informacji na temat funkcji wirtualnych, zobacz Funkcje wirtualne.
Poniższy kod pokazuje, jak wywołać funkcję wirtualną za pomocą funkcji wskaźnika do składowej:
// virtual_functions.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Base
{
public:
virtual void Print();
};
void (Base::* bfnPrint)() = &Base::Print;
void Base::Print()
{
cout << "Print function for class Base" << endl;
}
class Derived : public Base
{
public:
void Print(); // Print is still a virtual function.
};
void Derived::Print()
{
cout << "Print function for class Derived" << endl;
}
int main()
{
Base *bPtr;
Base bObject;
Derived dObject;
bPtr = &bObject; // Set pointer to address of bObject.
(bPtr->*bfnPrint)();
bPtr = &dObject; // Set pointer to address of dObject.
(bPtr->*bfnPrint)();
}
// Output:
// Print function for class Base
// Print function for class Derived
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla