Warum kann ich das nicht tun?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Warum kann ich das nicht tun?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Antworten:
Sie können nicht initialisieren a
und b
in, B
weil sie keine Mitglieder von sind B
. Sie sind Mitglieder von A
und A
können sie daher nur initialisieren. Sie können sie veröffentlichen und dann zuweisen. Dies B
wird jedoch nicht empfohlen, da dies die Kapselung zerstören würde. Erstellen Sie stattdessen einen Konstruktor in A
, damit B
(oder eine beliebige Unterklasse von A
) diese initialisiert werden kann:
class A
{
protected:
A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
// Change "protected" to "public" to allow others to instantiate A.
private:
int a, b; // Keep these variables private in A
};
class B : public A
{
public:
B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
{
}
};
a
und b
in , B::B()
weil sie privat sind. Sie können sie nicht initialisieren, da sie keine Mitglieder von sind class B
. Wenn Sie sie öffentlich gemacht oder geschützt haben, können Sie sie im Hauptteil von zuweisenB::B()
.
a
und b
..." 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
, da a
und b
sind Mitglieder A
, werden sie von initialisiert werden soll A
‚s Bauer, nicht von einigen Konstrukteuren der anderen Klasse (abgeleitet oder nicht).
Versuchen:
class A
{
int a, b;
protected: // or public:
A(int a, int b): a(a), b(b) {}
};
class B : public A
{
B() : A(0, 0) {}
};
Irgendwie hat niemand den einfachsten Weg aufgelistet:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Sie können nicht auf Basismitglieder in der Initialisierungsliste zugreifen, aber der Konstruktor selbst kann wie jede andere Elementmethode auf public
und protected
Mitglieder der Basisklasse zugreifen .
B
zugewiesen wird, und dann im B
Konstruktor des Konstruktors zugewiesen . Ich denke aber auch, dass der Compiler dies noch optimieren kann.
class A
wir uns nicht darauf verlassen a
und b
initialisiert werden. Bei jeder Implementierung von class C : public A
wird beispielsweise möglicherweise vergessen, aufzurufen a=0;
und a
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.
# include<stdio.h>
# include<iostream>
# include<conio.h>
using namespace std;
class Base{
public:
Base(int i, float f, double d): i(i), f(f), d(d)
{
}
virtual void Show()=0;
protected:
int i;
float f;
double d;
};
class Derived: public Base{
public:
Derived(int i, float f, double d): Base( i, f, d)
{
}
void Show()
{
cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
}
};
int main(){
Base * b = new Derived(10, 1.2, 3.89);
b->Show();
return 0;
}
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.
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
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:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
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.
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 Fall B() : 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 Mitglieder