Pourquoi je ne peux pas faire ça?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Pourquoi je ne peux pas faire ça?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Réponses:
Vous ne pouvez pas initialiser a
et b
in B
car ils ne sont pas membres de B
. Ils sont membres de A
, donc seuls A
peuvent les initialiser. Vous pouvez les rendre publics, puis les attribuer B
, mais ce n'est pas une option recommandée car cela détruirait l'encapsulation. Au lieu de cela, créez un constructeur A
pour permettre B
(ou une sous-classe de A
) de 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.
{
}
};
a
et b
en B::B()
car ils sont privés. Vous ne pouvez pas les initialiser car ils ne sont pas membres de class B
. Si vous les avez rendus publics ou protégés, vous pouvez les attribuer dans le corps de B::B()
.
a
et b
..." et l'ai changé en "Vous ne pouvez pas initialiser ..." sans m'assurer que le reste de la phrase avait du sens. Message modifié.
En laissant de côté le fait qu'ils sont private
, depuis a
et b
sont membres de A
, ils sont censés être initialisés par A
les constructeurs de, pas par les constructeurs d'une autre 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) {}
};
D'une manière ou d'une autre, personne n'a énuméré le moyen le plus simple:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
Vous ne pouvez pas membres de base accès dans la liste des initialiseur, mais le constructeur lui - même, comme toute autre méthode membre, peut accéder public
et les protected
membres de la classe de base.
B
est allouée, puis elle sera affectée à l'intérieur du B
constructeur de. Mais je pense aussi que le compilateur peut toujours optimiser cela.
class A
nous ne pouvons pas compter sur a
et en b
cours d'initialisation. Toute implémentation de class C : public A
, par exemple, peut oublier d'appeler a=0;
et ne pas être a
initialisée.
class A { int a = 0;};
), soit dans le constructeur de la classe de base. Les sous-classes peuvent toujours les réinitialiser dans leur constructeur si nécessaire.
# 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;
}
C'est un exemple de travail dans le cas où vous souhaitez initialiser les membres de données de classe de base présents dans l'objet de classe dérivée, alors que vous souhaitez pousser ces valeurs en interface via un appel de constructeur de classe dérivée.
Bien que cela soit utile dans de rares cas (si ce n'était pas le cas, la langue l'aurait permis directement), jetez un œil à l' idiome Base from Member . Ce n'est pas une solution sans code, vous devrez ajouter une couche supplémentaire d'héritage, mais cela fait le travail. Pour éviter le code standard, vous pouvez utiliser l'implémentation de boost
Pourquoi tu ne peux pas le faire? Parce que le langage ne vous permet pas d'initialiser les membres d'une classe de base dans la liste d'initialisation de la classe dérivée.
Comment pouvez-vous y parvenir? 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 de visibilité pour un membre de classe, la valeur par défaut est "privée". Vous devez rendre vos membres privés ou protégés si vous souhaitez y accéder dans une sous-classe.
Les classes agrégées, comme A dans votre exemple (*), doivent avoir leurs membres publics et ne pas avoir de constructeurs définis 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égation 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é, l'original class A
n'est pas un agrégat en raison de membres privés non statiques