Home > software > Böser Code: member pointer in C++

Böser Code: member pointer in C++

Vor einiger Zeit in ich auf etwas aufmerksam geworden, das mir erstauntes Kopfschütteln entlockt hat – member pointer.
Aber vorher etwas C++-Theorie 😉

Das Klassenkonstrukt in C++ kennt u.a. die Schlüsselwörter public und private, die dazu dienen den Zugriff auf so markierten Member der Klasse zu beschränken. public steht dabei für allgemeinen Lese- und Schreibzugriff, privat beschränkt den Zugriff auf Memberfunktionen der Klasse. Dazu ein kurzes Beispiel:

class someClass{
   public:
      int one;        // öffentliche Variable
      void f();
   private:
      int two;        // private Variable
};
...
someClass Instance;
...
Instance.one = 1;        // erlaubt
 
Instance.two = 2;        // verboten - compiler error

Member Pointer sind eine spezielle Form von Zeigern, die nur auf Member von Instanzen von der selben Klasse zeigen dürfen. Realisiert wird das durch relative Addressierung im Speicherbereich der Klasseninstanz. Für obriges Beispiel sieht das zum Beispiel so aus.

// pMember ist global und zeigt auf 'one' einer beliebigen Instanz von 'someClass'
int someClass::*pMember = &someClass::one;
...
Instance.*pMember = 5;     // erlaubt, da 'one' public ist
...
pMember = &someClass::two;     //    compiler error, da
Instance.*pMember = 23;            //     'two' private ist

Hübsche Syntax oder? 😉 Nebenbei ist ‘.*‘ keine Kombination aus Punkt- und Dereferenzierungsoperator, sondern stellt einen eigenständigen Operator für member pointer dar.
Bis hierhin ist das noch absolut stressfrei, da private greift und den Zugriff beschränkt. Anders sieht das allerdings aus, wenn der Zeiger seinen Inhalt innerhalb der Klasse bekommt. Hier kommt die Member-Funktion ‘f()‘ ins Spiel.

void someClass::f()
{
   pMember = &someClass::two;        // erlaubt, da innerhalb der Klasse!
}
...
Instance.f()                    // Sesam öffne dich:
                                 // ab hier hat private seine Bedeutung verloren !
 
Instance.*pMember = 42;        // erlaubt aber BÖSE :)

In der Praxis kommen Zeiger auf Member-Variablen recht selten vor. Pointer auf Member-Funktionen sind damit aber auch möglich und wohl sinnvoller. Zum Abschluss lass ich die Syntax nochmal für sich selbst sprechen.

void (someClass::*pFunc)() = &someClass::f;    // Deklaration
...
(someInstance.*pFunc)();                            // Aufruf

Categories: software Tags: , , ,
  1. No comments yet.
  1. No trackbacks yet.