This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
in204:cpp:syntax:class:deriving:constructor [2019/09/29 11:55] bmonsuez [Syntaxe] |
in204:cpp:syntax:class:deriving:constructor [2022/11/18 10:51] (current) |
||
---|---|---|---|
Line 25: | Line 25: | ||
- | ===== Syntaxe ===== | + | ===== Syntaxe d'un constructeur dans une classe dérivée ===== |
La syntaxe d'un constructeur d'une classe dérivée appelant les constructeurs de la classe de base est la suivante : | La syntaxe d'un constructeur d'une classe dérivée appelant les constructeurs de la classe de base est la suivante : | ||
Line 44: | Line 44: | ||
protected: | protected: | ||
+ | Cloth(): m_size(Cloth::S); | ||
explicit Cloth(Size theSize): m_size(theSize) | explicit Cloth(Size theSize): m_size(theSize) | ||
{} | {} | ||
Line 58: | Line 59: | ||
Pant(Cloth::Size theSize, unsigned theLength): | Pant(Cloth::Size theSize, unsigned theLength): | ||
Cloth(theSize), m_length(theLength) | Cloth(theSize), m_length(theLength) | ||
+ | {} | ||
+ | Pant(unsigned theLength): | ||
+ | m_length(theLength) | ||
{} | {} | ||
Pant(const Pant& anotherPant): | Pant(const Pant& anotherPant): | ||
Line 78: | Line 82: | ||
Dans ce cas de figure, la première opération consiste à initialisé le champs défini dans ''Pant'' et ensuite d'appelé le constructeur ''Cloth(Cloth::Size)'' pour initialiser la classe de base. Ceci peut avoir une importance quand l'initialisation d'un champ ou d'une classe requiert que la valeur définie pour un autre champ ou une autre classe soit déjà effectuée. | Dans ce cas de figure, la première opération consiste à initialisé le champs défini dans ''Pant'' et ensuite d'appelé le constructeur ''Cloth(Cloth::Size)'' pour initialiser la classe de base. Ceci peut avoir une importance quand l'initialisation d'un champ ou d'une classe requiert que la valeur définie pour un autre champ ou une autre classe soit déjà effectuée. | ||
+ | Considérons désormais la déclaration du constructeur ''Pant(unsigned)''. Ce constructeur se contente d'initialiser le champ ''m_length''. Il n'y a pas d'appel à un constructeur de la classe de base. | ||
+ | |||
+ | <code cpp> | ||
+ | Pant(unsigned theLength): | ||
+ | m_length(theLength) | ||
+ | {} | ||
+ | </code> | ||
+ | |||
+ | Mais il est nécessaire d'initialiser intégralement les extensions mais aussi la classe de base. Si aucun constructeur n'est appelé, C++ initialise la classe de base en appelant le constructeur par défaut. En fait, le code précédent est équivalent au code suivant : | ||
+ | |||
+ | <code cpp> | ||
+ | Pant(unsigned theLength): | ||
+ | m_length(theLength), Cloth() | ||
+ | {} | ||
+ | </code> | ||
+ | |||
+ | Ceci permet de garantir que l'ensemble des champs est bien initialisé par le constructeur. | ||
===== Le constructeur par défaut ===== | ===== Le constructeur par défaut ===== | ||
+ | Le [[in204:cpp:syntax:class:constructor:default|constructeur par défaut]] est le constructeur qui ne prend aucun argument. Les règles d'écriture dans une classe dérivée du constructeur par défaut sont identifiques à celles valables pour des constructeurs spécialisés pour une classe dérivée. | ||
+ | |||
+ | Cependant en l'absence de constructeurs spécialisé et d'une définition explicite du constructeur par défaut dans une classe dérivée, C++ définit un constructeur par défaut implicite qui est généré et a comme caractéristique les caractéristiques suivantes : | ||
+ | |||
+ | * Ce constructeur est public. | ||
+ | * Ce constructeur appelle pour chacun des champs de la classe et des classes de bases soit le constructeur, soit procède à l'affectation de la valeur par défaut, soit procède à l'initialisation par défaut du type (qui peut consister justement à ne rien faire). | ||
+ | * le corps du constructeur est vide. | ||
+ | |||
+ | <code cpp> | ||
+ | class MyClass: | ||
+ | public BaseClass, | ||
+ | private ImplementationClass | ||
+ | { | ||
+ | private: | ||
+ | int value; | ||
+ | public: | ||
+ | MyClass(): BaseClass(), ImplementationClass(), | ||
+ | value() // Correspond au constructeur par défaut généré automatiquement | ||
+ | // en C++. | ||
+ | {} | ||
+ | }; | ||
+ | </code> | ||
===== Le constructeur de recopie ===== | ===== Le constructeur de recopie ===== | ||
+ | |||
+ | Le [[in204:cpp:syntax:class:constructor:copy|constructeur de recopie]] est un constructeur qui a pour signature | ||
+ | ''ClassName(const ClassName&)'' où ''ClassName'' est le nom de la classe. | ||
+ | |||
+ | Si aucun constructeur de recopie n'est défini pour une classe héritant de plusieurs classes, un constructeur de recopie est automatiquement généré en C++. | ||
+ | |||
+ | * Ce constructeur est public, | ||
+ | * Ce constructeur effectue pour chacun des champs de la classe une opération de recopie. Si le type du champ est une classe, il appelle le constructeur de recopie défini par le type du champ, si le type du champ est un type simple, il effectue une copie mémoire du contenu du champ. Pour chacune des classes de bases, il appele le constructeur de recopie définie par cette classe de base. | ||
+ | * Le corps du constructeur est vide. | ||
+ | |||
+ | |||
+ | <code cpp> | ||
+ | class MyClass: | ||
+ | public BaseClass, | ||
+ | private ImplementationClass | ||
+ | { | ||
+ | private: | ||
+ | int value; | ||
+ | public: | ||
+ | MyClass(const MyClass& anotherClass): | ||
+ | BaseClass(anotherClass), | ||
+ | ImplementationClass(anotherClass), | ||
+ | value(anotherClass.value) | ||
+ | // Correspond au constructeur de recopie généré automatiquement | ||
+ | // en C++. | ||
+ | {} | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | Comme ''MyClass'' hérite de ''BaseClass'' et de ''ImplementationClass'', la conversion de ''anotherClass'' qui a pour type ''const MyClass&'' en une référence à un objet de type ''BaseClass'' ou ''Implementation'' est **toujours | ||
+ | possible** puisque que ''MyClass'' hérite de l'ensemble des champs et fonctions membres de ''BaseClass'' et de ''ImplementationClass'' et par extension pour toujours se comporter comme étant un objet ayant pour type ''BaseClass'' ou pour type ''ImplementationClass''. | ||