Comment puis-je initialiser les variables membres de la classe de base dans le constructeur de la classe dérivée?

Pourquoi je ne peux pas faire ça?

class A { public: int a, b; }; class B : public A { B() : A(), a(0), b(0) { } }; 

Vous ne pouvez pas initialiser a et b dans B car ils ne sont pas membres de B Ils sont membres de A , donc seul A peut les initialiser. Vous pouvez les rendre publics, puis les assigner dans B , mais ce n’est pas une option recommandée car cela détruirait l’encapsulation. Au lieu de cela, créez un constructeur dans A pour autoriser B (ou toute sous-classe de A ) à les initialiser:

 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. { } }; 

Laissant de côté le fait qu’elles sont private , puisque a et b sont membres de A , elles sont destinées à être initialisées par les constructeurs de A, et non par d’autres constructeurs de classe (dérivés ou non).

Essayer:

 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) {} } 

Bien que cela soit utile dans de rares cas (si ce n’était pas le cas, le langage l’aurait permis directement), jetez un coup d’œil à l’ idiome Base from Member . Ce n’est pas une solution sans code, vous devez append une couche supplémentaire d’inheritance, mais cela fait le travail. Pour éviter le code passe-partout, vous pouvez utiliser l’implémentation de boost

 # include # include # include 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 = "<
		      	

Pourquoi tu ne peux pas le faire? Parce que la langue ne vous permet pas d’initialiser une classe de base ‘membres dans la liste d’initialisation de la classe dérivée.

Comment pouvez-vous faire cela? Comme ça:

 class A { public: A(int a, int b) : a_(a), b_(b) {}; int a_, b_; }; class B : public A { public: B() : A(0,0) { } }; 

Si vous ne spécifiez pas la visibilité pour un membre de classe, sa valeur par défaut est “private”. Vous devez rendre vos membres privés ou protégés si vous souhaitez y accéder dans une sous-classe.

Les classes d’agrégat, comme A dans votre exemple (*), doivent avoir leurs membres publics et ne pas avoir de constructeur défini par l’utilisateur. Ils sont initialisés avec la liste d’initialisation, par exemple A a {0,0}; ou dans votre cas B() : A({0,0}){} . Les membres de la classe d’agrégat de base ne peuvent pas être initialisés individuellement dans le constructeur de la classe dérivée.

(*) Pour être précis, comme il a été correctement mentionné, la class A n’est pas un agrégat dû à des membres non statiques privés