8
votes

Comment utiliser un STD :: auto_ptr dans une classe à laquelle vous devez copier la construction?

J'ai la classe foo code> contenant un membre STD :: auto_ptr que je voudrais copier construire, mais cela ne semble pas être autorisé. Il y a une chose similaire pour la mission. Voir l'exemple suivant:

struct foo
{
private:
    int _a;
    std::string _b;
    std::auto_ptr< bar > _c;

public:
    foo(const foo& rhs)
        :   _a(rhs._a)
        ,   _b(rhs._b)

        ,   _c(rhs._c)
                // error: Cannot mutate rhs._c to give up ownership - D'Oh!
    {
    }

    foo& operator=(const foo& rhs)
    {
         _a = rhs._a;
         _b = rhs._b;

         _c = rhs._c;
             // error: Same problem again.
    }
};


0 commentaires

9 Réponses :


8
votes

Comme vous l'avez découvert, vous ne pouvez pas copier un std :: auto_ptr comme ça. Après la copie qui possède l'objet pointé? Au lieu de cela, vous devez utiliser un pointeur intelligent compté de référence. Le Boost Bibliothèque a un Shared_PTR Vous pouvez utiliser.


0 commentaires

16
votes

Vous voudrez peut-être essayer le code suivant:

    foo(const foo& rhs)
        :   _a(rhs._a)
        ,   _b(rhs._b)
        ,   _c(_rhs._c.get() ? new bar(*_rhs._c.get()) : 0)
    {
    }


1 commentaires

Toujours la meilleure réponse même après la modification. FOO aura besoin de copier ou de partager une barre, et auto_ptr ne partage pas bien. Comme la copie est maintenant exclue, vous aurez besoin d'un partage_ptr.



0
votes

L'idée entière du auto_ptr est qu'il n'y a qu'un seul propriétaire de l'objet renvoyé à l'objet. Cela implique que vous ne puissiez pas copier le pointeur sans supprimer la propriété initiale.

Comme vous ne pouvez pas le copier, vous ne pouvez pas également copier un objet contenant an auto_ptr .

Vous pouvez essayer d'utiliser le déplacement-sémantique par ex. Utilisation de std :: échange au lieu de copie.


2 commentaires

-1, il est trivial de copier un objet contenant un auto_ptr . Vous le faites en créant un nouveau auto_ptr pointant vers un T. copié


@Msalters: Mais alors vous ne copiez pas le auto_ptr. Vous copiez la référence à l'objet.



3
votes

Tout d'abord, j'éviterais AUTO_PTR

Transfert de propriété est bon dans certains scénarios, mais je trouve qu'ils sont rares et que les bibliothèques intelligentes "à part entière" sont maintenant disponibles facilement. (IIRC AUTO_PTR était un compromis pour inclure au moins un exemple dans la bibliothèque standard, sans que les retards qu'une bonne implémentation aurait requis).

voir, par exemple ici
ou ici

Décidez de la sémantique < BR> La copie de FOO détient-elle une référence à la même instance de barre? Dans ce cas, utilisez boost :: partagé_ptr ou ( boost :: intrusion_ptr ) ou une bibliothèque similaire.

ou une copie profonde doit-elle être créée? (Cela peut parfois être requis, par exemple lors d'un état créé par retard). Je ne connais aucune mise en œuvre standard de ce concept, mais il ne faut pas complexe de construire cela similaire aux pointeurs intelligents existants. xxx


0 commentaires

1
votes

Le std :: auto_ptr est un bon outil permettant de gérer l'objet dynamique en C ++, mais afin de l'utiliser efficacement, il est important de fonctionner à quel point_ptr fonctionne. Cet article explique pourquoi, quand et où ce pointeur intelligent doit être utilisé.

Dans votre cas, tout d'abord, vous devez décider de ce que vous voulez faire avec l'objet à l'intérieur de votre auto_ptr. Devrait-il être cloné ou partagé?

S'il doit être cloné, assurez-vous qu'il dispose d'un constructeur de copie, puis de créer une nouvelle auto_ptr qui contient une copie de votre objet voir la réponse de Adam Badura .

S'il devrait être partagé, vous devez utiliser boost :: Shared_ptr comme MARTIN LIVERSAGE suggéré.


0 commentaires

0
votes

Mon premier choix serait d'éviter AUTO_PTR dans cette situation. Mais si j'étais sauvegardé contre un mur, je pourrais essayer d'utiliser le mot-clé mutable dans la déclaration de _c - cela lui permettra d'être modifié même d'une référence de const.


0 commentaires

-1
votes

Vous ne pouvez pas utiliser Constons références dans un constructeur de copie ou un opérateur d'affectation qui implique un auto_ptr code>. Supprimer le const. En d'autres termes, utilisez des déclarations telles que

foo(foo & rhs);
foo & operator=(foo & rhs);


4 commentaires

Sûr que vous pouvez les utiliser; Vous devez juste remplacer le constructeur de copie implicite et l'opérateur d'affectation.


Selon la norme, ils sont le constructeur de copie implicite et l'opérateur d'affectation. J'ai donné des références. Si vous connaissez des implémentations, cela ne fonctionnera pas, veuillez nous dire.


Votre mise en œuvre fonctionnera et je pense que j'étais incorrect sur la partie générée implicitement. Ce que j'étais en désaccord avec la première phrase que vous ne pouvez pas utiliser Constons références dans un constructeur de copie avec Aut_ptr's. Vous pouvez, vous devez simplement les faire faire quelque chose de différent du comportement par défaut.


Qu'est-ce que tu veux faire? Vous ne pouvez pas simplement copier un Auto_PTR <> d'un argument de const. Vous pouvez copier profonde, qui n'est pas désiré ici. Vous pouvez créer deux auto_ptr <> s pointant à la même chose, ce qui est une catastrophe en attente de se produire.



1
votes

Si j'ai une classe contenant un auto_ptr et que je souhaite une sémantique de copie approfonie, je ne le fais génération que pour les classes ayant un opérateur de copie virtuel, c'est-à-dire clone ().

alors, dans le constructeur de copie, j'initialise le auto_ptr sur un clone () de l'autre; par exemple xxx

clone () est généralement implémenté comme suit: xxx

Nous imposons la condition que t soit clonable, Mais cette condition est essentiellement imposée par une classe copiable avec un membre auto_ptr.


0 commentaires

0
votes

Compte tenu de la modification, il apparaît alors que vous souhaitez transmettre une sémantique de propriété.

Dans ce cas, vous souhaiterez que votre constructeur de copie et votre opérateur d'affectation acceptent les références de non-const à leurs arguments et effectuer l'initialisation / l'affectation là-bas.


0 commentaires