Warum kann ich das nicht tun?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
c++
inheritance
Amrhassan
quelle
quelle
Antworten:
Sie können nicht initialisieren
a
undb
in,B
weil sie keine Mitglieder von sindB
. Sie sind Mitglieder vonA
undA
können sie daher nur initialisieren. Sie können sie veröffentlichen und dann zuweisen. DiesB
wird jedoch nicht empfohlen, da dies die Kapselung zerstören würde. Erstellen Sie stattdessen einen Konstruktor inA
, damitB
(oder eine beliebige Unterklasse vonA
) diese initialisiert werden kann:quelle
a
undb
in ,B::B()
weil sie privat sind. Sie können sie nicht initialisieren, da sie keine Mitglieder von sindclass B
. Wenn Sie sie öffentlich gemacht oder geschützt haben, können Sie sie im Hauptteil von zuweisenB::B()
.a
undb
..." ein und änderte sie in "Sie können nicht initialisieren ...", ohne sicherzustellen, dass der Rest des Satzes Sinn machte. Beitrag bearbeitet.Abgesehen von der Tatsache , dass sie
private
, daa
undb
sind MitgliederA
, werden sie von initialisiert werden sollA
‚s Bauer, nicht von einigen Konstrukteuren der anderen Klasse (abgeleitet oder nicht).Versuchen:
quelle
Irgendwie hat niemand den einfachsten Weg aufgelistet:
Sie können nicht auf Basismitglieder in der Initialisierungsliste zugreifen, aber der Konstruktor selbst kann wie jede andere Elementmethode auf
public
undprotected
Mitglieder der Basisklasse zugreifen .quelle
B
zugewiesen wird, und dann imB
Konstruktor des Konstruktors zugewiesen . Ich denke aber auch, dass der Compiler dies noch optimieren kann.class A
wir uns nicht darauf verlassena
undb
initialisiert werden. Bei jeder Implementierung vonclass C : public A
wird beispielsweise möglicherweise vergessen, aufzurufena=0;
unda
nicht initialisiert zu bleiben.class A { int a = 0;};
) oder im Konstruktor der Basisklasse. Die Unterklassen können sie nach Bedarf in ihrem Konstruktor neu initialisieren.Dies ist ein funktionierendes Beispiel für den Fall, dass Sie die im abgeleiteten Klassenobjekt vorhandenen Datenelemente der Basisklasse initialisieren möchten, während Sie diese Werte über den Aufruf des Konstruktors für abgeleitete Klassen an die Schnittstelle weiterleiten möchten.
quelle
Dies ist zwar in seltenen Fällen nützlich (wenn dies nicht der Fall wäre, hätte die Sprache dies direkt zugelassen), werfen Sie jedoch einen Blick auf die Basis aus der Mitgliedersprache . Es ist keine codefreie Lösung, Sie müssten eine zusätzliche Vererbungsebene hinzufügen, aber sie erledigt den Job. Um Boilerplate-Code zu vermeiden, können Sie die Implementierung von boost verwenden
quelle
Warum kannst du es nicht tun? Da die Sprache es Ihnen nicht erlaubt, Mitglieder einer Basisklasse in der Initialisierungsliste der abgeleiteten Klasse zu initialisieren.
Wie können Sie das erreichen? So was:
quelle
Wenn Sie keine Sichtbarkeit für ein Klassenmitglied angeben, wird standardmäßig "privat" verwendet. Sie sollten Ihre Mitglieder privat oder geschützt machen, wenn Sie in einer Unterklasse auf sie zugreifen möchten.
quelle
Aggregierte Klassen wie A in Ihrem Beispiel (*) müssen ihre Mitglieder öffentlich haben und dürfen keine benutzerdefinierten Konstruktoren haben. Sie werden mit der Initialisierungsliste initialisiert, z. B.
A a {0,0};
oder in Ihrem FallB() : A({0,0}){}
. Die Mitglieder der Basisaggregatklasse können im Konstruktor der abgeleiteten Klasse nicht einzeln initialisiert werden.(*) Um genau zu sein, ist das Original, wie richtig erwähnt,
class A
kein Aggregat aufgrund privater nicht statischer Mitgliederquelle