Namespaces
Variants

Default constructors

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Default constructor
Copy constructor
Move constructor (C++11)
Templates
Miscellaneous

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

1) Déclaration d'un constructeur par défaut dans la définition de classe.
2-4) Définition d'un constructeur par défaut à l'intérieur de la définition de classe.
3) Le constructeur par défaut est explicitement par défaut.
4) Le constructeur par défaut est supprimé.
5,6) Définition d'un constructeur par défaut en dehors de la définition de classe (la classe doit contenir une déclaration (1) ).
6) Le constructeur par défaut est explicitement par défaut.

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 T est trivial, alors pour chaque union U qui est soit T soit un membre union anonyme de T , si le premier membre variant (le cas échéant) de U a un type à durée de vie implicite , le constructeur par défaut de T commence la durée de vie de ce membre s'il n'est pas le membre actif de son union.

(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 T est défini comme supprimé si l'une des conditions suivantes est satisfaite :

  • T possède un membre de données non statique de type référence sans initialiseur par défaut.
  • T est une classe non- union et (depuis C++26) possède un membre de données non variant non statique non- const-default-constructible de type qualifié const (ou éventuellement un tableau multidimensionnel de celui-ci) sans initialiseur de membre par défaut.
  • T est une union et tous ses membres variant sont de type qualifié const (ou éventuellement un tableau multidimensionnel de celui-ci).
  • T est une classe non-union et tous les membres de toute union anonyme membre sont de type qualifié const (ou éventuellement un tableau multidimensionnel de celui-ci).
(jusqu'à C++26)
  • Étant donné un type de classe M , T possède un sous-objet potentiellement construit obj de type M (ou éventuellement un tableau multidimensionnel de celui-ci), et l'une des conditions suivantes est satisfaite :
  • M possède un destructeur qui est supprimé ou inaccessible depuis le constructeur par défaut , et soit obj est non variant soit obj possède un initialiseur de membre par défaut (depuis C++26) .
  • Toutes les conditions suivantes sont satisfaites :
  • obj n'est pas un membre de données non statique avec un initialiseur par défaut.
  • obj n'est pas un membre variant d'une union où un autre membre de données non statique possède un initialiseur par défaut (jusqu'à C++26) .
  • La résolution de surcharge appliquée pour trouver le constructeur par défaut de M ne résulte pas en un candidat utilisable , ou dans le cas où obj est un membre variant, sélectionne une fonction non triviale (jusqu'à C++26) .

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) .
  • T n'a pas de fonctions membres virtuelles.
  • T n'a pas de classes de base virtuelles.
  • T n'a pas de membres non statiques avec des initialiseurs par défaut.
(depuis C++11)
  • Chaque base directe de T a un constructeur par défaut trivial.
  • Chaque membre non statique de type classe (ou tableau de ceux-ci) a un constructeur par défaut trivial.
(jusqu'en C++26)
  • Soit T est une union, soit chaque membre non statique non variant de type classe (ou tableau de ceux-ci) a un constructeur par défaut trivial.
(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

Voir aussi