Default constructors
Un constructeur par défaut est un constructeur qui peut être appelé sans arguments.
Table des matières |
Syntaxe
class-name
(
parameter-list
(optionnel)
);
|
(1) | ||||||||
class-name
(
parameter-list
(optionnel)
)
function-body
|
(2) | ||||||||
class-name
() = default;
|
(3) | (depuis C++11) | |||||||
class-name
(
parameter-list
(optionnel)
) = delete;
|
(4) | (depuis C++11) | |||||||
class-name
::
class-name
(
parameter-list
(optionnel)
)
function-body
|
(5) | ||||||||
class-name
::
class-name
() = default;
|
(6) | (depuis C++11) | |||||||
| class-name | - | la classe dont le constructeur par défaut est déclaré |
| parameter-list | - | une liste de paramètres où tous les paramètres (sauf les parameter packs ) (depuis C++11) ont des arguments par défaut |
| function-body | - | le corps de fonction du constructeur par défaut |
Explication
Les constructeurs par défaut sont appelés lors des initialisations par défaut et des initialisations par valeur .
Constructeur par défaut implicitement déclaré
S'il n'y a pas de constructeur ou de modèle de constructeur déclaré par l'utilisateur pour un type de classe, le compilateur déclarera implicitement un constructeur par défaut comme un inline public membre de sa classe.
Le constructeur par défaut implicitement déclaré (ou par défaut lors de sa première déclaration) a une spécification d'exception comme décrit dans la spécification d'exception dynamique (jusqu'à C++17) la spécification noexcept (depuis C++17) .
Constructeur par défaut implicitement défini
Si le constructeur est implicitement déclaré (jusqu'à C++11) le constructeur par défaut implicitement déclaré ou explicitement par défaut n'est pas défini comme supprimé (depuis C++11) , il est implicitement défini par le compilateur lorsqu'il est odr-used ou nécessaire pour l'évaluation constante ou lorsqu'il est explicitement par défaut après sa première déclaration (depuis C++11) .
|
Si un constructeur par défaut d'une
classe union-like
|
(depuis C++26) |
Un (jusqu'en C++26) Sinon, un (depuis C++26) constructeur par défaut implicitement défini a le même effet qu'un constructeur défini par l'utilisateur avec un corps vide et une liste d'initialisation vide. C'est-à-dire qu'il appelle les constructeurs par défaut des bases et des membres non statiques de cette classe. Les types de classe avec un constructeur fourni par l'utilisateur vide peuvent être traités différemment de ceux avec un constructeur par défaut implicitement défini lors de l' initialisation par valeur .
|
Si cela satisfait aux exigences d'un constexpr constructeur (jusqu'en C++23) constexpr fonction (depuis C++23) , le constructeur généré est constexpr . Si certains constructeurs définis par l'utilisateur sont présents, l'utilisateur peut toujours forcer la génération automatique d'un constructeur par défaut par le compilateur qui serait autrement implicitement déclaré avec le mot-clé default . |
(depuis C++11) |
Constructeur par défaut supprimé
Le constructeur par défaut implicitement déclaré ou explicitement défini par défaut pour la classe
Si aucun constructeur défini par l'utilisateur n'est présent et que le constructeur par défaut implicitement déclaré n'est pas trivial, l'utilisateur peut toujours empêcher la génération automatique d'un constructeur par défaut implicitement défini par le compilateur avec le mot-clé delete . |
(depuis C++11) |
Constructeur par défaut trivial
Le constructeur par défaut pour la classe
T
est trivial si toutes les conditions suivantes sont satisfaites :
- Le constructeur est implicitement-déclaré (jusqu'en C++11) non fourni par l'utilisateur (depuis C++11) .
-
Tn'a pas de fonctions membres virtuelles. -
Tn'a pas de classes de base virtuelles.
|
(depuis C++11) |
-
Chaque base directe de
Ta un constructeur par défaut trivial.
|
(jusqu'en C++26) |
|
(depuis C++26) |
Un constructeur par défaut trivial est un constructeur qui n'effectue aucune action. Tous les types de données compatibles avec le langage C (types POD) sont trivialement constructibles par défaut.
Constructeur par défaut éligible
|
Un constructeur par défaut est éligible s'il est soit déclaré par l'utilisateur, soit implicitement déclaré et définissable. |
(jusqu'en C++11) |
|
Un constructeur par défaut est éligible s'il n'est pas supprimé. |
(depuis C++11)
(jusqu'en C++20) |
|
Un constructeur par défaut est éligible si toutes les conditions suivantes sont satisfaites :
|
(depuis C++20) |
La trivialité des constructeurs par défaut éligibles détermine si la classe est un type à durée de vie implicite , et si la classe est un type trivialement copiable .
Notes
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_trivial_union
|
202502L
|
(C++26) | Assouplissement des exigences de trivialité pour les fonctions membres spéciales des unions |
Exemple
struct A { int x; A(int x = 1): x(x) {} // constructeur par défaut défini par l'utilisateur }; struct B : A { // B::B() est implicitement défini, appelle A::A() }; struct C { A a; // C::C() est implicitement défini, appelle A::A() }; struct D : A { D(int y) : A(y) {} // D::D() n'est pas déclaré car un autre constructeur existe }; struct E : A { E(int y) : A(y) {} E() = default; // explicitement défini par défaut, appelle A::A() }; struct F { int& ref; // membre référence const int c; // membre const // F::F() est implicitement défini comme supprimé }; // constructeur de copie déclaré par l'utilisateur (fourni, supprimé ou par défaut) // empêche la génération implicite d'un constructeur par défaut struct G { G(const G&) {} // G::G() est implicitement défini comme supprimé }; struct H { H(const H&) = delete; // H::H() est implicitement défini comme supprimé }; struct I { I(const I&) = default; // I::I() est implicitement défini comme supprimé }; int main() { A a; B b; C c; // D d; // erreur de compilation E e; // F f; // erreur de compilation // G g; // erreur de compilation // H h; // erreur de compilation // I i; // erreur de compilation }
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| CWG 1353 | C++11 |
les conditions où les constructeurs par défaut implicitement déclarés sont
définis comme supprimés ne prenaient pas en compte les types de tableaux multidimensionnels |
prendre en compte ces types |
| CWG 2084 | C++11 |
les initialiseurs de membres par défaut n'avaient aucun effet sur le fait
qu'un constructeur par défaut par défaut d'une union soit supprimé |
ils empêchent le constructeur par défaut par défaut
d'être supprimé |
| CWG 2595 | C++20 |
un constructeur par défaut n'était pas éligible s'il existe
un autre constructeur par défaut qui est plus contraint mais ne satisfait pas ses contraintes associées |
il peut être éligible dans ce cas |
| CWG 2871 | C++98 |
un constructeur par défaut serait implicitement déclaré
même s'il existe un constructeur template déclaré par l'utilisateur |
pas de déclaration implicite
dans ce cas |