6
votes

Copie Constructeur pour transférer la propriété d'un article_ptr

J'ai besoin d'écrire un constructeur de copie qui transférer également la propriété d'un membre unique_ptr de l'objet en cours de copie. La situation est la suivante: xxx

Comment puis-je implémenter le constructeur de copie pour A ?


3 commentaires

Donc, lorsque vous faites une copie, vous voulez rendre l'original invalide? Je suggérerais de supprimer le constructeur de copie et de rendre la classe mobile uniquement.


Si, avec l'original, vous voulez dire que l'objet original a oui, il devrait être "Transferref" en tant que membre de la classe B. Pouvez-vous vous donner un exemple de cela?


@GabrielecswoShsosh passez un peu de temps à lire les questions / réponses sur le Tag Motion-Sémantique .


3 Réponses :


6
votes

Votre intention ou votre approche est fausse, je suppose.

La copie-constructeur est destiné à créer un em> copier em> de l'argument, mais comme unique_ptr code> maintient la propriété excédentaire On ne peut pas en faire une copie. Vous pourrait em> faire en fait un membre unique_ptr mutable code>, puis déplacez la ressource qu'il pointe sur le constructeur de copie mais qui serait absolument insensé (c'est ce que std :: auto_ptr code> fait et c'est pourquoi il est obsolète). P>

Par conséquent, vous devez: P>

  • ajoutez un constructeur de déplacement à A et B (+ Coopy-Constructor supprimé) Li>
  • Switch de unique_ptr code> à Shared_ptr code>, mais seulement si c est en réalité destiné à être partagé li> ul>

    Il y a aussi une troisième option, qui consiste à effectuer une copie de l'objet pointée par le constructeur de copie unique_ptr dans la copy-constructeur, c'est-à-dire: p>

    A::A(const A& a) : c_(std::unique_ptr<C>(a.c_ ? new C(*a.c_) : nullptr)) {
    }
    


6 commentaires

Je n'appellerais pas l'intention tort. Il convient parfaitement à créer une interface de modélisation A type régulier que le type emballé ne peut pas exposer naturellement.


Je ne suis pas d'accord avec toi. Vous pouvez copier un objet qui contient uniques_ptr. Par exemple, je pourrais mettre en œuvre une classe LinkedList qui contient uniques_ptr en tant que pointeur pour l'élément suivant. Cela signifie-t-il que je ne peux pas ou ne devrait pas copier une liste aimée? Je souhaiterais peut-être copier la liste liée elle-même et enregistrer cette copie dans le fichier unique_ptr de l'objet copié


@Davidhaim, mais op veut transférer la propriété en copy-constructeur - c'est ce que le titre de la question dit. Je considère que c'est une mauvaise approche.


@Davidhaim en fait, Adam Romanek a raison parce que mon intention est de transférer la propriété, de ne pas copier l'objet pointé par le fichier unique_ptr. Puis-je demander un exemple de constructeur de déplacement pour cet exemple?


@Gabrielecswoosh, Ici vous avez: Melpon.org/wandbox/permlink/bbvgsx31iuofzf4s . Veuillez noter que le compilateur génère le même code pour vous par défaut lorsque vous avez un type de déplacement uniquement en tant que membre, par exemple. unique_ptr: Melpon.org/wandbox/permlink/7alooxzsomoslifa (NOTE AUCUNE COPIE / MOVE Constructeurs dans un et cela fonctionne toujours comme prévu)


Merci, en fait, j'ai d'autres variables membres dans un type qui ne se déplacent pas seulement (c'est-à-dire un flotteur et un int), alors j'ai besoin de l'écrire!



3
votes

techniquement, à

" Écrivez un constructeur de copie qui transférer également la propriété d'un membre unique_ptr de l'objet en cours de copie

Vous pouvez simplement faire ceci: xxx

car un constructeur de copie peut également avoir cette signature, plus deux autres, en plus du plus conventionnel Mauvais (const mauvais &) .

J'ai nommé que la classe mauvais parce que c'est vraiment mauvais, il n'a pas de sens de faire cette chose sauf en tant que sabotage de quelqu'un Code d'autre.

au lieu d'un constructeur de copie qui ne copie pas,

  • implémente un constructeur de déplacement qui se déplace ou

  • Implémentez un constructeur de copie ordinaire qui copie ou

  • changer la conception de la classe à par exemple. propriété partagée .


0 commentaires

4
votes

Évidemment, vous ne pouvez pas simplement faire une affectation de std :: unique_ptr s car son opérateur d'affectation est supprimé. Ceci est intentionnel de forcer le programmeur à définir le comportement qu'il veut.

  1. Le nouvel élément prend la propriété de C _ , invalidant l'élément d'origine.
  2. Le nouvel élément fait une copie de c _ , conservant la validité des éléments d'origine.
  3. Le nouvel élément partage la propriété de c _ de sorte que les éléments nouveaux et originaux font référence au même objet.

    dans cas 1 Ce que vous cherchez est un constructeur de déplacement, et le constructeur de déplacement par défaut fonctionnera bien. Donc, vous n'avez pas besoin d'écrire un code, vous pouvez simplement faire: xxx

    Notez que Temp n'est pas valide après sa déplacement .

    dans CAS 2 Vous devez ajouter un constructeur de copie personnalisé sur A pour créer une copie du C _ : xxx

    après avoir défini cela dans A vous pouvez faire: xxx

    Notez que cela dépend du constructeur de copie C est fonctionnel.

    dans cas 3 vous Besoin de modifier fondamentalement modifier A à partir d'un std :: unique_ptr à l'aide d'un std :: partagé_ptr , donc la définition de c_ < / code> deviendrait: xxx

    Votre construction de c _ serait identique à ce que vous utilisez déjà pour le std :: unique_ptr version de c _ . Ainsi, en utilisant les implémentations par défaut que vous pouvez faire: xxx

    et maintenant foo et bar point sur le même C objet et proportionnez-la. Cet objet partagé ne sera pas supprimé tant que tout partagé_ptr S réféencage a été supprimé.


0 commentaires