Perché non posso farlo?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Perché non posso farlo?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Risposte:
Non è possibile inizializzare ae bin Bperché non sono membri di B. Sono membri di A, quindi Apossono solo inizializzarli. Puoi renderli pubblici, quindi eseguire l'assegnazione in B, ma questa non è un'opzione consigliata poiché distruggerebbe l'incapsulamento. Invece, crea un costruttore Aper consentire B(o qualsiasi sottoclasse di A) di inizializzarli:
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 e bin B::B()perché sono privati. Non è possibile inizializzarli perché non sono membri di class B. Se li hai resi pubblici o protetti potresti assegnarli nel corpo di B::B().
ae b..." e l'ho cambiato in "Non puoi inizializzare ..." senza assicurarmi che il resto della frase avesse un senso. Post modificato.
Lasciando da parte il fatto che sono private, poiché ae bsono membri di A, devono essere inizializzati dai Acostruttori di, non dai costruttori di qualche altra classe (derivati o meno).
Provare:
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) {}
};
In qualche modo, nessuno ha elencato il modo più semplice:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Non è possibile organi di base di accesso nella lista di inizializzazione, ma il costruttore stesso, proprio come qualsiasi altro metodo membro, può accedere publice protectedmembri della classe base.
Bviene allocata l'istanza di , quindi verrà assegnato all'interno del Bcostruttore di. Ma penso anche che il compilatore possa ancora ottimizzarlo.
class Anon possiamo fare affidamento su ae bessere inizializzati. Qualsiasi implementazione di class C : public A, ad esempio, potrebbe dimenticare di chiamare a=0;e lasciare anon inizializzato.
class A { int a = 0;};) o nel costruttore della classe base. Le sottoclassi possono ancora reinizializzarle nel loro costruttore secondo necessità.
# 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;
}
È un esempio funzionante nel caso in cui si desideri inizializzare i membri dei dati della classe Base presenti nell'oggetto della classe Derived, mentre si desidera eseguire il push di questi valori interfacciandosi tramite la chiamata del costruttore della classe Derived.
Anche se questo è utile in rari casi (se così non fosse, la lingua lo avrebbe permesso direttamente), dai un'occhiata al linguaggio Base from Member . Non è una soluzione priva di codice, dovresti aggiungere un ulteriore livello di ereditarietà, ma porta a termine il lavoro. Per evitare il codice boilerplate è possibile utilizzare l'implementazione di boost
Perché non puoi farlo? Perché la lingua non consente di inizializzare i membri di una classe base nell'elenco di inizializzatori della classe derivata.
Come puoi farlo? Come questo:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
Se non specifichi la visibilità per un membro della classe, il valore predefinito è "privato". Devi rendere i tuoi membri privati o protetti se desideri accedervi in una sottoclasse.
Le classi aggregate, come A nel tuo esempio (*), devono avere i loro membri pubblici e non avere costruttori definiti dall'utente. Sono inizializzati con l'elenco degli inizializzatori, ad esempio A a {0,0};o nel tuo caso B() : A({0,0}){}. I membri della classe aggregata di base non possono essere inizializzati individualmente nel costruttore della classe derivata.
(*) Per essere precisi, come è stato giustamente ricordato, l'originale class Anon è un aggregato dovuto a membri privati non statici