Maison  >  Article  >  développement back-end  >  Pourquoi un constructeur privé par défaut en C fonctionne-t-il lorsqu'il est utilisé avec des accolades mais échoue-t-il avec des parenthèses ?

Pourquoi un constructeur privé par défaut en C fonctionne-t-il lorsqu'il est utilisé avec des accolades mais échoue-t-il avec des parenthèses ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-11 14:00:03380parcourir

Why does a private default constructor in C   work when used with curly braces but fail with parentheses?

Ombre privé du constructeur par défaut

Lors de la déclaration d'un type avec l'intention de rendre son constructeur par défaut privé, l'utilisation du mot-clé default peut ne pas atteindre l'objectif résultat souhaité, comme illustré dans l'extrait de code suivant :

class C {
    C() = default;
};

int main() {
    C c;           // error: C::C() is private within this context (g++)
                   // error: calling a private constructor of class 'C' (clang++)
                   // error C2248: 'C::C' cannot access private member declared in class 'C' (MSVC)
    auto c2 = C(); // error: as above
}

Étonnamment, ce code génère des erreurs bien qu'il rende explicitement le constructeur privé. Cependant, le code suivant se compile avec succès :

class C {
    C() = default;
};

int main() {
    C c{};         // OK on all compilers
    auto c2 = C{}; // OK on all compilers
} 

Pourquoi le constructeur se comporte-t-il différemment lorsqu'il est utilisé avec des accolades ?

C 14 Default Constructor Defaultness

La clé réside dans la norme C 14 (8.4.2/5 [dcl.fct.def.default]), qui définit une fonction « fournie par l'utilisateur » comme une fonction « déclarée par l'utilisateur et non explicitement définie par défaut ou supprimée. sur sa première déclaration. Cela implique que le constructeur par défaut dans notre exemple n'est pas considéré comme fourni par l'utilisateur puisqu'il a été explicitement défini par défaut.

Illumination du constructeur agrégé

En conséquence, la classe C a aucun constructeur fourni par l'utilisateur. Il est donc classé comme un agrégat selon 8.5.1/1 [dcl.init.aggr], qui stipule qu'un agrégat est « un tableau ou une classe sans constructeurs fournis par l'utilisateur, sans aucun constructeur non statique privé ou protégé ». membres de données, pas de classes de base et pas de fonctions virtuelles. {} même s'ils ont des constructeurs privés. Cette règle vise à simplifier l'initialisation des agrégats, tels que les tableaux et les structures, qui contiennent généralement plusieurs membres.

Par conséquent, le constructeur de la classe C, bien que marqué comme privé, peut toujours être utilisé entre accolades car la classe elle-même est considérée comme un agrégat.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn