Zugegeben, dieser Fragetitel klingt ziemlich genau so wie die Frage, die Sie von Mike wiederholt gestellt haben. Ich habe eine ganze Reihe von Fragen auf die gleiche Art und Weise gefunden, aber keine war meine Frage.C++ geschützt: Zugriff auf das geschützte Member der Base aus der abgeleiteten Klasse nicht möglich
Zunächst einmal würde Ich mag ein paar Punkte für den Kontext dieser Frage zu klären:
1, C++ Zugriffskontrolle arbeitet auf einer Klassenbasis eher als Instanz Basis. Daher ist der folgende Code vollständig gültig.
class Base
{
protected:
int b_;
public:
bool IsEqual(const Base& another) const
{
return another.b_ == b_; // access another instance's protected member
}
};
2, ich völlig verstehen, warum der folgende Code nicht gültig ist - eine weitere Geschwister Instanz sein kann.
class Derived : public Base
{
public:
// to correct the problem, change the Base& to Derived&
bool IsEqual_Another(const Base& another) const
{
return another.b_ == b_;
}
};
Jetzt ist die Zeit meine eigentliche Frage zu entladen:
in der abgeleiteten Klasse Angenommen, ich habe eine Reihe von Grundinstanzen. So effektiv, abgeleitet IS A Base (IS-A-Beziehung), und Abgeleitet besteht aus Base (Composite-Beziehung). Ich habe von irgendwo gelesen, dass dies (bezieht sich auf das Design von IS-A und Has-A) ein Designgeruch ist und ich niemals ein solches Szenario haben sollte. Nun, das mathematische Konzept von Fractals zum Beispiel kann sowohl durch IS-A- als auch Has-A-Beziehungen modelliert werden. Lassen Sie uns jedoch die Meinung über Design für einen Moment ignorieren und konzentrieren Sie sich nur auf das technische Problem.
class Derived : public Base
{
protected:
Base base_;
public:
bool IsEqual_Another(const Derived& another) const
{
return another.b_ == b_;
}
void TestFunc()
{
int b = base_.b_; // fail here
}
};
Die Fehlermeldung angegeben hat bereits den Fehler sehr deutlich, so gibt es keine Notwendigkeit, dass in Ihrer Antwort zu wiederholen:
Main.cpp:140:7: error: ‘int Base::b_’ is protected int b_; ^ Main.cpp:162:22: error: within this context int b = base_.b_;
Wirklich, nach den folgenden zwei Tatsachen, sollte der Code über Arbeit :
1, C++ - Zugriffssteuerung funktioniert auf Klassenbasis statt Instanzenbasis (daher nicht sagen, dass ich nur auf Derived zugreifen kann b_; Ich kann nicht auf geschützte Elemente einer Standalone-Basisinstanz zugreifen - es ist auf Klasse Basis).
2, Fehlermeldung "innerhalb dieses Kontexts" - der Kontext ist abgeleitet (Ich habe versucht, auf das geschützte Mitglied einer Basisinstanz von Derived zuzugreifen. Es ist das eigentliche Merkmal eines geschützten Mitglieds - es sollte darauf zugegriffen werden können von innerhalb der Basis oder etwas, das von Basis ableitet.
warum wird der Compiler mir diesen Fehler geben?
Hallo Bo. Danke für die schnelle Antwort. Hier ist der verwirrende Teil: Der Klärungspunkt 1, bevor ich meine Frage löste, ist genau das, wovon ich mich selbst nicht überzeugen kann. Sie sehen, ich habe auf das geschützte Mitglied einer völlig unabhängigen Base-Instanz zugegriffen und der Compiler war damit einverstanden. – h9uest
Ich hätte das als Quizfrage versäumt. Hast du eine Begründung dafür? Schließlich ist Derived eine Base, die es nicht unangemessen erscheinen lässt, mit anderen Bases auf privater Basis sozusagen zumindest geschützt zu interagieren ;-). Weil Basen das * können * können. Warum macht die Ableitung von Base eine Klasse - schließlich eine Basis, unter anderem! - diese Fähigkeit verlieren? –
Um eine Antwort auf meine eigene Frage zu geben: Eric Lippert hat über die äquivalente Regel in C# geschrieben und scheint einfach zu glauben, dass weniger strenge Semantik für 'protected' nicht ausreichend schützen würde (in seinem Kommentar zu seinem Blog https: // blogs .msdn.microsoft.com/ericlippert/2005/11/09/why-cant-i-Zugriff-a-protected-member-from-a-derived-Klasse/# comment-2844). Er führt das nicht aus, aber ich nehme folgendes an: Bei gegebenem Säugetier A könnte der Benutzercode den geschützten Säugetierzustand von A "legal" durch ein dummes Geschwister-Säugetier B ändern, ein "Angriff", gegen den A nicht "schützen" könnte die Designer. –