
mikrofoniert
Ich bin gestern auf einen Fehler gestoßen, und obwohl es einfach ist, ihn zu umgehen, wollte ich sicherstellen, dass ich C++ richtig verstehe.
Ich habe eine Basisklasse mit einem geschützten Mitglied:
class Base
{
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
Das kompiliert und funktioniert einwandfrei. Jetzt erweitere ich Base, möchte aber immer noch b verwenden:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
Beachten Sie das in diesem Fall DoSomething
nimmt immer noch einen Verweis auf a Base
nicht Derived
. Ich würde erwarten, dass ich noch Zugriff haben kann that.b
Innen Derived
aber ich bekomme ein cannot access protected member
Fehler (MSVC 8.0 – gcc noch nicht ausprobiert).
Offensichtlich wird ein öffentlicher Getter hinzugefügt b
hat das Problem gelöst, aber ich habe mich gefragt, warum ich keinen direkten Zugriff darauf haben konnte b
. Ich denke, dass bei Verwendung der öffentlichen Vererbung die geschützten Variablen für die abgeleitete Klasse immer noch sichtbar sind.

SLaks
Eine Klasse kann nur auf geschützte Member von Instanzen dieser Klasse oder einer abgeleiteten Klasse zugreifen. Es kann nicht auf geschützte Member von Instanzen einer Elternklasse oder Cousinklasse zugreifen.
In Ihrem Fall die Derived
Klasse kann nur auf die zugreifen b
geschütztes Mitglied von Derived
Instanzen, nicht die von Base
Instanzen.
Ändern des Konstruktors, um a zu nehmen Derived
Instanz wird das Problem lösen.
protected
Mitglieder erreichbar:
- durch
this
Zeiger
- oder zu denselben typgeschützten Membern, auch wenn sie in base deklariert sind
- oder von Freundesklassen, Funktionen
Um Ihren Fall zu lösen, können Sie eine der letzten beiden Optionen verwenden.
Akzeptieren Sie Derived in Derived::DoSomething oder deklarieren Sie Derived friend
zur Basis:
class Derived;
class Base
{
friend class Derived;
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
In einigen Fällen können Sie auch öffentliche Getter in Betracht ziehen.
Wie gesagt, so funktioniert die Sprache.
Eine andere Lösung besteht darin, die Vererbung auszunutzen und an die übergeordnete Methode zu übergeben:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
Base::DoSomething(that);
d=0;
}
};
Sie haben Zugriff auf die geschützten Mitglieder von Derived
aber nicht die von Base
(auch wenn der einzige Grund, warum es ein geschütztes Mitglied von ist Derived
ist, weil es von geerbt wird Base
)

Martin.Bof
Du kannst es mit versuchen static_cast(pBase)->Base::protected_member …
class Base
{
protected:
int b;
public:
...
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b += static_cast<const Derived*>(&that)->Base::b;
d=0;
}
void DoSomething(const Base* that)
{
b += static_cast<const Derived*>(that)->Base::b;
d=0;
}
};

Vishnu Singh
class Derived : public Base
{
protected:
int d;
public:
void DoSomething()
{
b+=this->b;
d=0;
}
};
//this will work

Stiv Zhops
Nach dem Hack für stl habe ich einen kleinen Code geschrieben, der das Problem des Zugriffs auf die geschützten Member in der abgeleiteten Klasse zu lösen scheint
#include <iostream>
class B
{
protected:
int a;
public:
void dosmth()
{
a = 4;
}
void print() {std::cout<<"a="<<a<<std::endl;}
};
class D: private B
{
public:
void dosmth(B &b)
{
b.*&D::a = 5;
}
};
int main(int argc, const char * argv[]) {
B b;
D d;
b.dosmth();
b.print();
d.dosmth(b);
b.print();
return 0;
}
Drucke
a=4
a=5
9897800cookie-checkZugreifen auf geschützte Member in einer abgeleiteten Klasseyes
Kasse gotw.ca/gotw/076.htm (Hinweis: Verwenden Sie dieses Zeug nicht im Produktionscode).
– Brian
14. Juli 2010 um 17:32 Uhr