Quand souhaitez-vous utiliser un std::auto ptr au lieu de boost::ptr?

nous sommes presque passés à l'utilisation boost::shared_ptr dans tout notre code, cependant nous avons encore quelques cas isolés où nous utilisons <!-Y compris les cours de singleton:

template < typename TYPE >
class SharedSingleton
{
public: 
    static TYPE& Instance()
    {
        if (_ptrInstance.get() == NULL)
            _ptrInstance.reset(new TYPE);
        return *_ptrInstance;
    }

protected: 
    SharedSingleton() {};

private:
    static std::auto_ptr < TYPE > _ptrInstance;
};

j'ai dit qu'il y a une très bonne raison pour laquelle cela n'a pas été fait shared_ptr, mais pour ma vie Je ne peux pas comprendre pourquoi? Je sais que auto_ptr seront éventuellement marqués comme dépréciés dans le prochain standard, donc j'aimerais savoir ce que / comment je peux remplacer ceci la mise en œuvre.

Aussi, existe-il d'autres raisons pour lesquelles vous devez envisager d'utiliser un auto_ptr au lieu d'un shared_ptr? et voyez-vous des problèmes à passer à shared_ptr dans le futur?


Edit:

  1. Donc, en réponse à "je peux remplacer auto_ptrshared_ptr dans le code ci-dessus", la réponse est oui, mais je vais prendre un petit gain de performance.
  2. Quand auto_ptr est éventuellement marqués comme dépréciés et nous passons à std::shared_ptr, nous aurons besoin de tester en profondeur notre code pour nous assurer que nous respectons les différentes sémantiques de propriété.
17
demandé sur Alan 2009-08-04 16:58:57

3 réponses

auto_ptr et shared_ptr résoudre des problèmes complètement différents. L'un ne remplace pas l'autre.

auto_ptr est une mince wrapper autour de pointeurs pour mettre en œuvre RAII sémantique, de sorte que les ressources soient toujours libérées, même en présence d'exceptions. auto_ptr n'effectue aucun comptage de référence ou similaire, il ne fait pas pointer plusieurs pointeurs vers le même objet lors de la création de copies. En fait, c'est très différent. auto_ptr est l'une des rares classes où l'opérateur d'affectation modifie l' source objet. Considérez ce bouchon éhonté de la auto_ptr page wikipedia:

int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i

notez comment exécuter

y = x;

modifie non seulement y mais aussi. x.

boost::shared_ptr modèle permet de gérer plusieurs pointeurs vers le même objet, et l'objet n'est supprimé après la dernière référence à il est allé hors de portée. Cette fonctionnalité n'est pas utile dans votre scénario, qui (tente de) implémenter un Singleton. Dans votre scénario, il y a toujours 0 références à 1 référence au seul objet de la classe, s'il y en a.

En substance, auto_ptr objets et shared_ptr les objets ont une sémantique complètement différente (c'est pourquoi vous ne pouvez pas utiliser le premier dans des conteneurs, mais le faire avec le second est très bien), et j'espère que vous avez de bons tests pour attraper toutes les régressions que vous avez introduites lors du portage de votre code. : -}

35
répondu Frerich Raabe 2010-07-08 12:09:39

d'Autres ont répondu pourquoi ce code utilise un auto_ptr au lieu d'un shared_ptr. Pour répondre à vos autres questions:

Comment puis-je remplacer cette implémentation?

Utiliser boost::scoped_ptr ou unique_ptr (disponible dans Boost et le nouveau standard c++). Les deux scoped_ptr et unique_ptr fournissent une propriété stricte (et aucun comptage de référence au-dessus), et ils évitent la sémantique surprenante delete-on-copy de auto_ptr.

Aussi, sont il y a d'autres raisons pour lesquelles vous envisagez d'utiliser un auto_ptr au lieu d'un shared_ptr? Et voyez-vous des problèmes pour le déplacement à shared_ptr dans l'avenir?

personnellement, je n'utiliserais pas un auto_ptr. Supprimer sur la copie n'est tout simplement pas intuitif. Herb Sutter semble être d'accord. De commutation scoped_ptr,unique_ptr, ou shared_ptr ne devrait pas poser de problèmes. Plus précisément, shared_ptr devrait être un remplaçant de drop-in si vous ne vous souciez pas de la référence compte au-dessus. scoped_ptr est un remplacement si vous n'utilisez pas auto_ptr's de transfert de propriété des capacités. Si vous êtes à l'aide de transfert de propriété, puis unique_ptr est presque un remplacement de drop-in, sauf que vous devez à la place appeler explicitement move pour transférer la propriété. Voir ici pour un exemple.

14
répondu Josh Kelley 2009-08-04 13:48:14

auto_ptr est le seul type de pointeur intelligent que j'utilise. Je l'utilise parce que je N'utilise pas Boost, et parce que je préfère généralement mes cours orientés business / application à explicitement définir la sémantique de la suppression et l'ordre, plutôt que de dépendre de collections de, ou individuels, pointeurs intelligents.

1
répondu 2009-08-04 13:07:56