Dlaczego nie mogę tego zrobić?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Dlaczego nie mogę tego zrobić?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Odpowiedzi:
Nie można zainicjować ai bna Bponieważ nie są członkami B. Są członkami A, więc tylko Amogą je inicjalizować. Możesz je upublicznić, a następnie wykonać przypisanie B, ale nie jest to zalecana opcja, ponieważ zniszczyłaby hermetyzację. Zamiast tego utwórz konstruktor w programie, Aaby umożliwić B(lub dowolną podklasę A) ich zainicjowanie:
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 i bna B::B()ponieważ są prywatne. Nie możesz ich zainicjować, ponieważ nie są członkami class B. Jeśli upubliczniłeś je lub chroniłeś, możesz przypisać je w treści B::B().
ai b...” i zmieniłem to na „Nie możesz zainicjować ...” bez upewnienia się, że reszta zdania ma sens. Edytowano post.
Pomijając fakt, że są private, ponieważ są członkami ai bsą członkami A, mają być inicjowane przez Akonstruktory, a nie przez konstruktory innej klasy (pochodne lub nie).
Próbować:
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) {}
};
Jakoś nikt nie wymienił najprostszego sposobu:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Nie możesz uzyskać dostępu do podstawowych elementów członkowskich na liście inicjalizatora, ale sam konstruktor, podobnie jak każda inna metoda członkowska, może uzyskać dostęp publici protectedelementy członkowskie klasy bazowej.
Bprzydzieleniu instancji programu zostanie ona najpierw zainicjowana domyślnie , a następnie zostanie przypisana wewnątrz Bkonstruktora. Ale myślę też, że kompilator nadal może to zoptymalizować.
class Anie możemy polegać ai bjest inicjowany. Każda implementacja class C : public A, na przykład, może zapomnieć o wywołaniu a=0;i pozostawić aniezainicjowaną.
class A { int a = 0;};) lub w konstruktorze klasy bazowej. Podklasy nadal mogą w razie potrzeby ponownie zainicjować je w swoim konstruktorze.
# 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;
}
Jest to działający przykład na wypadek, gdybyś chciał zainicjować składowe danych klasy bazowej obecne w obiekcie klasy pochodnej, podczas gdy chcesz przekazać te wartości za pośrednictwem wywołania konstruktora klasy pochodnej.
Chociaż jest to przydatne w rzadkich przypadkach (gdyby tak nie było, język pozwoliłby na to bezpośrednio), spójrz na idiom Base from Member . To nie jest rozwiązanie wolne od kodu, musiałbyś dodać dodatkową warstwę dziedziczenia, ale wykonuje to zadanie. Aby uniknąć standardowego kodu, możesz użyć implementacji boost
Dlaczego nie możesz tego zrobić? Ponieważ język nie pozwala na inicjalizację elementów członkowskich klasy bazowej na liście inicjatorów klasy pochodnej.
Jak możesz to zrobić? Lubię to:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
Jeśli nie określisz widoczności dla członka klasy, domyślnie będzie to „prywatna”. Powinieneś uczynić swoich członków prywatnymi lub chronionymi, jeśli chcesz uzyskać do nich dostęp w podklasie.
Klasy agregujące, takie jak A w Twoim przykładzie (*), muszą mieć swoje elementy członkowskie jako publiczne i nie mogą mieć konstruktorów zdefiniowanych przez użytkownika. Są one inicjowane z listą inicjalizacyjną, np. A a {0,0};Lub w twoim przypadku B() : A({0,0}){}. Elementy członkowskie podstawowej klasy zagregowanej nie mogą być indywidualnie inicjowane w konstruktorze klasy pochodnej.
(*) Mówiąc dokładniej, jak słusznie wspomniano, oryginał class Anie jest agregatem ze względu na prywatne niestatyczne elementy członkowskie