Neomi
2007-07-07, 00:30:06
Für eine saubere Kapselung brauche ich den Zugriffsmodus "protected" in manchen Klassen, aber in wenigen Situationen funktioniert das einfach nicht so wie erwartet. Hier erstmal das Kernproblem:
class A
{
protected:
int a;
A *pa;
public:
A() : a(0), pa(NULL) {}
};
class B : A
{
public:
B()
{
a = 1; // Zugriff über this, funzt
pa = this; // Zugriff über this, funzt
a = ((B*) pa)->a; // Unschöner Hack, funzt
a = pa->a; // Fehler
}
};
Wenn ein Objekt auf geschützte Variablen der Basisklasse zugreifen will, dann geht das über den this-Pointer, weil der natürlich den Typ der eigenen Klasse hat. Mit einem Pointer, der auf die eigene Klasse typisiert ist, kann man dann auch auf die geschützten Variablen der Basisklasse von anderen Objekten zugreifen. Mit einem Pointer, der den Typ der Basisklasse hat, geht das aber auf einmal nicht mehr. Definitiv betroffen sind VS 2002 und 2005.
Ich habe zwar jetzt mehrere Möglichkeiten, das Problem zu umgehen, davon gefällt mir aber keine:
1. die entsprechenden Variablen in der Basisklasse auf "public" setzen (bäh, die sollen schon geschützt sein)
3. Basisklasse mit "friend"-Deklarationen fluten (auch blöd, das Interface sollte nicht für jede Erweiterung angerührt werden müssen)
2. Pointer umcasten, obwohl es ein ganz anderer Typ sein kann (bäh, potentiell gefährlich und sieht im Code doof aus)
Kennt jemand eine saubere Lösung für dieses Problem? Warum tritt das überhaupt auf?
class A
{
protected:
int a;
A *pa;
public:
A() : a(0), pa(NULL) {}
};
class B : A
{
public:
B()
{
a = 1; // Zugriff über this, funzt
pa = this; // Zugriff über this, funzt
a = ((B*) pa)->a; // Unschöner Hack, funzt
a = pa->a; // Fehler
}
};
Wenn ein Objekt auf geschützte Variablen der Basisklasse zugreifen will, dann geht das über den this-Pointer, weil der natürlich den Typ der eigenen Klasse hat. Mit einem Pointer, der auf die eigene Klasse typisiert ist, kann man dann auch auf die geschützten Variablen der Basisklasse von anderen Objekten zugreifen. Mit einem Pointer, der den Typ der Basisklasse hat, geht das aber auf einmal nicht mehr. Definitiv betroffen sind VS 2002 und 2005.
Ich habe zwar jetzt mehrere Möglichkeiten, das Problem zu umgehen, davon gefällt mir aber keine:
1. die entsprechenden Variablen in der Basisklasse auf "public" setzen (bäh, die sollen schon geschützt sein)
3. Basisklasse mit "friend"-Deklarationen fluten (auch blöd, das Interface sollte nicht für jede Erweiterung angerührt werden müssen)
2. Pointer umcasten, obwohl es ein ganz anderer Typ sein kann (bäh, potentiell gefährlich und sieht im Code doof aus)
Kennt jemand eine saubere Lösung für dieses Problem? Warum tritt das überhaupt auf?