11
votes

Pourquoi Compiler fournit un constructeur de copie par défaut

Je voulais savoir pourquoi Compiler fournit un constructeur de copie par défaut..qui la stratégie de cette idée.

Merci d'avance.


1 commentaires

La réponse générale à la raison pour laquelle le compilateur fait quelque chose est qu'il doit mettre en œuvre les règles de la langue. Cela s'applique aussi ici.


10 Réponses :


1
votes

Vous économiser du temps? Si vous avez une classe simple (c'est-à-dire si vous pouvez facilement copier construire tous ses éléments), vous n'avez alors pas besoin d'en écrire un.


0 commentaires

0
votes

Je ne suis pas sûr de ce que la "ligne officielle est" (ne pas avoir le livre de Strastroup près de moi) et je suis sûr que quelqu'un va le creuser.

Cependant, dans la plupart des cas, des copies peu profondes et une initialisation par défaut sont "assez bonnes", donc c'est Mieux vaut pour le compilateur de leur fournir que le développerexplicité les écrit.

Si le développeur a écrit ces constructeurs de copies triviaux et les champs change ultérieurement, il appartient à cet utilisateur de faire les changements et qu'il pourrait y avoir des erreurs sérieuses s'il oublie (par exemple, quels sont ces champs construits comme?).

Par les utilisateurs n'écrochant que des constructeurs de copies quand il est vraiment nécessaire de faire quelque chose de fantaisie (comme une copie profonde), vous réduisez la fréquence de ces erreurs.


0 commentaires

6
votes

Par exemple, lorsque vous passez une instance par valeur, comment le compilateur pourrait-il générer un?


4 commentaires

Vous pourriez avoir le compilateur se plaindre de l'absence d'un constructeur de copie, je suppose.


Ensuite, je pense que vous auriez des problèmes de compatibilité en arrière. Une classe et une structure sont similaires. En C ++, une structure n'est qu'une classe avec des méthodes et des attributs publics par défaut. Cela signifie que lorsque vous déclarez une structure à partir d'un programme C compilé en tant que C ++, il existe un constructeur de copie implicite que vous devez supposer qu'il est là pour une compatibilité en arrière. Déplacez-le en cours et vous avez la situation que nous connaissons.


Vous pouvez dire qu'une fois n'importe quel CTOR défini, une copie CTOR n'est plus fournie par défaut. Cela serait toujours compatible avec C.


Stroustrup aurait pu définir une différence supplémentaire entre la classe et la structure, dans cette structure dispose d'une copie par défaut CTOR et de classe. Trop tard pour cela maintenant.



3
votes

Je ne sais pas pourquoi il a été conçu à l'origine de cette façon. Mais comme un utilisateur, je peux dire pourquoi je suis content d'avoir fait.

  1. Si vous utilisez tous les types Raii ou POD, un constructeur de copie fera la bonne chose
  2. Copy Constructeurs n'a pas besoin de penser ni de maintenance, ils fonctionnent simplement # 1

    Je ressens la même chose à propos de l'opérateur d'affectation par défaut. La plupart des gens a) définissent leur constructeur de copie / égale à l'opérateur de manière incorrecte ou ne parviennent pas à le maintenir. J'ai supprimé beaucoup de bogues en code C ++ en passant aux types RAII et en supprimant les opérateurs codés à la main / Copie Constructeurs.


0 commentaires

27
votes

d'une question connexe (mais pas la même) - Pourquoi les compilateurs C ++ ne définissent pas l'opérateur == et opérateur! =? :

Stroustrup a déclaré ceci sur le constructeur de copie par défaut dans "la conception et l'évolution de C ++" (section 11.4.1 - Contrôle de la copie):

Je considère personnellement qu'il est malheureux que les opérations de copie soient définies par défaut et j'interdisons la copie d'objets de plusieurs de mes classes. Cependant, C ++ a hérité de son affectation par défaut et de ses constructeurs de copies de C, et ils sont fréquemment utilisés.

La réponse est donc qu'elle a été incluse à contrecotionnellement par Stroustrup pour la compatibilité à l'arrière avec C (probablement la cause de la plupart des verrues de C ++, mais aussi probablement la principale raison de la popularité de C ++).

Pour mes propres buts, dans mon IDE, l'extrait que j'utilise pour de nouvelles classes contient des déclarations d'un opérateur d'affectation privée et du constructeur de copie de sorte que lorsque je gène une nouvelle classe, je n'obtiens pas d'affectation par défaut et d'opérations de copie - je dois explicitement Supprimer la déclaration de ces opérations de la section privée: Section Si je veux que le compilateur puisse les générer pour moi.


6 commentaires

une classe de base telle que Boost :: Non gère la même chose de plus succincte


Je voudrais le mieux comme ça comme ceci: fournir un CTOR par défaut par défaut, mais uniquement s'il n'y a pas d'autre CTOR. S'il y en a, on peut faire = par défaut comme Richard Spectacles pour C ++ 0x et encore une bonne performance. Qu'est-ce que tu en penses?


@Phil - Je suis d'accord, mais mon extrait d'être utilise actuellement la méthode "à l'ancienne" en raison de l'inertie / la paresse (de ce n'est pas vraiment cassé, alors aucun effort ne va dans la variété de la fixation) et il n'a aucune dépendance. L'utilisation d'une classe de base privée non gourmable signifie que le fichier .cpp a besoin de #include "non-couchable.h". Pourrait ne pas être une grande excuse, mais c'est ce que j'ai. Notez que je nettoie souvent cela pour utiliser une base non gênante, car je pense que c'est une meilleure façon. Je devrais vraiment réparer mon extrait.


@LITB -ARE Vous parlez de la CTOR par défaut ou de la copie générée par le compilateur? Ma compréhension de C ++ 0X est que ce que vous décrivez sera le comportement des CTORS par défaut. Copier CTORS sera toujours généré automatiquement si nécessaire, sauf désactivation explicitement (en utilisant l'une des techniques existantes ou l'utilisation du mot clé ). J'imagine qu'il y a trop de code existant qui dépend de cela pour rendre un changement plus radical possible. Encore une fois, je ne suis pas un expert C ++ 0x, alors je pourrai que tout simplement se tromper.


oh je suis désolé je voulais dire "copier cors" -.-


@LITB: Je ne suis pas sûr de quelle raison il y aurait contre votre idée que les CTors de copie automatiques sont désactivés lorsqu'il existe une CTOR explicitement définie (comme le CTOR par défaut est dans ce cas). Je ne peux pas penser à une raison de top de ma tête. Évidemment, il serait difficile / impossible à faire à ce stade, mais cela aurait pu être un bon terrain d'entente si cela avait été fait initialement ...



1
votes

Si vous avez un struct utilisé par code C, un constructeur de copie par défaut doit être là pour préserver la sémantique de copier C struct.


0 commentaires

0
votes

Je pense que vous en arrivez à partir de la mauvaise direction - si le compilateur pouvait écrire un constructeur de copie «par défaut» complet et correct pour chaque classe ou structure, personne ne se plaindre, n'est-ce pas? Le problème est que le compilateur ne peut pas le faire de manière fiable, donc pour ces cas, vous devez écrire le vôtre, remplacer la valeur par défaut.


0 commentaires

3
votes

Quelques points:

Il est important de pouvoir contrôler si un objet peut ou ne peut pas être copié.

Si vous ne voulez pas qu'un objet puisse Soyez copié, vous pouvez alors déclarer le constructeur de copie privé (et en C ++ 0x vous pourrez dire = Supprimer ). Ceci est inchangé avec votre proposition cependant, le problème est simplement inversé, c'est-à-dire. Vous pouvez prévoir une question comme: "Pourquoi le compilateur ne génère pas un constructeur de copie par défaut lorsqu'il sait quoi faire?"

Ceci sera également adressé dans C ++ 0x, car je pense qu'il y a un < code> = drapeau par défaut qui vous permettra de spécifier-le: xxx

Il est avantageux de permettre au compilateur de mettre en œuvre la meilleure version possible de la copie constructeur.

Mise à l'écart, le compilateur est aujourd'hui capable de choisir la technique la plus efficace de copie de l'objet. Par exemple, il peut simplement utiliser MemCY avec l'objet si It sait que c'est sûr de le faire.

Avec votre proposition, pour obtenir une optimation similaire aujourd'hui, le compilateur aurait besoin de Pour analyser le corps du constructeur pour vérifier que cela ne fait que si la copie peu profonde, tous les membres. Non seulement ce non trivial est non seulement, il ne peut généralement se produire que lorsque le corps du constructeur est visible pour toutes les unités de traduction

in c ++ 0x = par défaut autour de cela.

Je ne serais pas surpris si, pour que les outils de C ++ 0x, les compilateurs et les outils d'analyse statique commencent à générer des avertissements sur "Membres par défaut implicites de style ancien".


3 commentaires

Le nouveau C ++ 0x défaut et Supprimer pour les constructeurs générés par le compilateur et les fonctions spéciales seront les bienvenus. Toutefois, note que pour l'affaire COPY-CORTOR, ma compréhension est que le compilateur générera toujours un par défaut dans tous les mêmes cas que ce qu'il le fait aujourd'hui - le mot clé est un moyen utile et simple d'empêcher Cela (en d'autres termes, il y aura peu de besoin pour par défaut à utiliser pour la copie-CTOR). Compatibilité Pesky Backwards.


@Michael Burr: Oui, tu as raison. Le comportement existant des compilateurs concernant les membres par défaut implicites restera inchangé. Comme je l'ai dit dans la réponse, la seule lueur de l'espoir que vous avez est que «= supprimer» et '= défaut' sont manna du ciel pour coder les normes (et bien sûr des outils d'analyse statique). Leur présence permet aux outils de mettre en évidence des classes que le développeur n'a pas l'intention de copier explicitement (c'est-à-dire à l'aide d'un constructeur de copie par défaut).


@Richard: Ce serait vraiment un bon outil de diagnostic ajouté.



8
votes

de Le langage de programmation C ++ , section 11.3.4 Copie

... Pour les types où le constructeur de copie par défaut a la sémantique appropriée, je préfère compter sur cette valeur par défaut. C'est moins verbeux que tout ce que je peux écrire et que les gens doivent comprendre la valeur par défaut. En outre, les compilateurs connaissent la valeur par défaut et ses possibilités d'optimisation possibles. De plus, la rédaction de la copie MARDWise à la main est fastidieuse et exposée aux erreurs pour les classes avec de nombreux membres de données.

Fondamentalement, j'ai lu que le constructeur de copie par défaut vous permet d'économiser les efforts, vous permet de gagner des erreurs causées par Tedium et permet d'optimiser votre code en supprimant la tentation de l'optimisation de la main (en laissant le compilateur le faire) .


6 commentaires

Ce disant est assez étendu de ce qu'il dit dans "Conception et évolution de C ++", HMM.


@LITB: Les deux passages semblent être quelque peu en attente. Peut-être que Stroustup les a initialement compris à contrecœur, puis les embrassa plus tard?


Je ne pense pas que cela soit conflit avec ce qui est dit dans D & E. Notez que la déclaration ici est qualifiée par "où le rétrécissement de la copie par défaut a la sématique droite". Ce qui est dit en D & E, c'est qu'il désactive souvent explicitement la copie générée automatiquement CORT, car elle n'a souvent pas la bonne semitique, et qu'il aurait aimé que la copie par défaut CORT n'était pas générée automatiquement (mais ses mains étaient nouées) . Dans CPL, il dise que si Vous allez simplement copier des bits, laissez le compilateur le faire pour vous.


Ils ne contredit pas à l'avant, je pense, mais ces deux phrases sont très étranges, je pense: "Je considère personnellement qu'il est malheureux que les opérations de copie soient définies par défaut" - "également, les compilateurs connaissent la valeur par défaut et son optimisation possible. Opportunités. En outre, la rédaction de la copie MARDise à la main est fastidieuse et exposée aux erreurs pour les classes avec de nombreux membres de données. ". @Michael, à la fin, je pense que vous avez raison et dans CPL, ses dictons sont basées sur le statu quo, tandis que dans le livre de conception, il nous montre ce qu'il pense vraiment à ce statut.


@Michael Burr: Je pense que la différence de libellé entre "Je considère personnellement cela malheureux que les opérations de copie sont définies par défaut ..." et "... i préférez à dépend de cette valeur par défaut. " (met l'accent sur le mien) est ce qui est déroutant. Je conviens que la qualification de "... où le constructeur de copie par défaut a la bonne sémantique ..." Nullifie à peu près le conflit perçu.


L'idiome à désactiver est court, doux et bien compris. Un coup d'œil et un lecteur sait ce qui est destiné. Si les valeurs par défaut n'étaient pas une partie de C ++, codage de la main Le comportement par défaut actuel n'est pas court et doux. Les lecteurs devraient vérifier que chaque domaine est effectivement copié ou autre chose. IMHO Cette décision a été devenue la manière la plus prudente.



0
votes

Parce que c ++ n'est pas recueilli, cela vous oblige à garder une trace de tous les propriétaires de pointeur, qui est en pratique impossible à faire, à moins que vous ne simplifiez que le problème en utilisant beaucoup de copier sur tout le lieu, donc au moins vous savez qui possède à qui le possède La copie et rend incidemment votre programme plus lentement qu'une poubelle collectée une. Les constructeurs de copies générés automatiquement sont un clou dans le cercueil qui a été placé là-bas pour cacher le trou béant vers l'enfer qui est nouveau et supprime.


0 commentaires