C++11 initialiseur de membre de la liste de vs dans-classe d'initialiseur?
Quelle est la différence entre ces modes d'initialisation de l'objet membre de variables en C++11 ? Est-il une autre voie ? de quelle façon est meilleure (performance) ?:
class any {
public:
obj s = obj("value");
any(){}
};
Ou
class any {
public:
obj s;
any(): s("value"){}
};
Grâce.
- Ils sont les mêmes.
- Je suis d'accord, ils sont les mêmes. Je voulais juste ajouter que pour de plus amples informations, vous pouvez lire "Le Langage de Programmation C++ 4ème Édition de la section" 17.4.4.
- Très similaire à le C++11 membres de l'initialisation de la fonction à la déclaration faite initialisation des listes obsolète?
Vous devez vous connecter pour publier un commentaire.
Non, ce sont des pas la même.
La différence entre eux est la même qui s'applique pour direct-initialisation vs copier-initialisation, ce qui est subtil, mais souvent très déroutant.
§12.6.2 [classe.de la base.init]:
§8.5 [dcl.init]:
De l'initialisation d'un non-membre de données statiques sur un membres de l'initialiseur-liste suit les règles de direct-initialisation, qui ne crée pas d'intermédiaire temporaires qui doivent être déplacés ou copiés (si compilé sans copier-élision), ni le type de la donnée membre doit être copiable/mobile (même si la copie est élidée). En outre, un direct-initialisation introduit un contexte explicite, tandis qu'un copier-initialisation est non-explicite (si un constructeur sélectionné pour l'initialisation est
explicit
, le programme ne compile pas).En d'autres termes, la
obj s = obj("value");
syntaxe ne compile pas siobj
est déclarée comme suit:ou:
Comme un exemple concret, tandis que le dessous ne compile pas:
ce sera:
Avec un copier-élision activé les deux ont des performances identiques. Avec copier-élision désactivé, il est une copie supplémentaire/constructeur de déplacement appeler chaque instanciation lorsque le copier-initialisation syntaxe est utilisée (que
obj s = obj("value");
est l'une des).La corset ou égal initialiseur syntaxe permet d'effectuer une direct de la liste d'initialisation ainsi:
Quelques autres différences qui méritent d'être mentionnées sont:
obj s{"value"}
est alloué sur le tas, puiss
sera alloué sur le tas. Si vous devez allouer des membres de données sur pile/tas dépend des décisions de conception et d'utilisation de ces objetsLes deux exemples suivants sont équivalents.
Mais seulement si le type est copiable ou mobiliers (vérifiez par vous-même) et NRVO est réellement fait (tout à mi-chemin décent compilateur va le faire comme une question de cours).
Mais si vous avez eu beaucoup de constructeurs et de constructeur de chaînage étaient inappropriées, la première méthode vous permettra de ne pas se répéter.
Aussi, vous pouvez utiliser cette méthode pour définir des agrégats avec des valeurs par défaut différentes de l'agrégat-initialisation pour (certains) membres depuis le C++14.
Ils sont les mêmes.
N'est ni mieux que les autres en termes de performances, et il n'y a pas d'autre façon d'initialiser eux.
Au profit de la classe d'initialisation (le premier dans votre exemple), c'est que l'ordre d'initialisation est implicite. Dans initialiser la liste, vous devez explicitement état de la commande et les compilateurs pour les avertir de l'ordre d'initialisation si vous obtenez la commande incorrecte.
De la norme:
Si vous prenez la commande de mal dans votre liste, GCC va se plaindre:
L'avantage d'initialiser les listes est peut-être une question de goût, et la liste est explicite, généralement dans le fichier source. Dans la classe est implicite (sans aucun doute), et se trouve généralement dans le fichier d'en-tête.