2010-01-23 5 views
3

Je passais par la documentation auto_ptr sur ce lien auto_ptr Il y a quelque chose que je ne pouvais pas comprendre complètement pourquoi cela est fait. Dans la section d'interface, il y a deux déclarations pour son constructeur de copiePourquoi l'interface pour auto_ptr spécifie-t-elle deux constructeurs de type copy-construct

1)

auto_ptr(auto_ptr<X>&) throw(); 

2)

template <class Y> 
    auto_ptr(auto_ptr<Y>&) throw(); 

Quel est le but est-ce pour.

+0

Le titre de cette question doit être changé en "Pourquoi l'interface de auto_ptr spécifie-t-elle deux constructeurs de type copy-constructor?" – Omnifarious

+0

fait, j'étais confus quand j'ai vu cette interface et ne pouvais pas penser à un bon titre :) –

Répondre

5

Il est là au cas où vous pouvez convertir implicitement les pointeurs:

struct base {}; 
struct derived : base {}; 

std::auto_ptr<derived> d(new derived); 
std::auto_ptr<base> b(d); // converts 

En outre, vous n'avez pas demandé, mais vous remarquerez que le constructeur de copie est non-const. C'est parce que le auto_ptr prendra possession du pointeur. Dans l'exemple ci-dessus, après b est construit, d tient à rien. Cela rend auto_ptr impropre à l'utilisation dans des conteneurs, car il ne peut pas être copié.

C++ 0x fossés auto_ptr et en fait un appelé unique_ptr. Ce pointeur a les mêmes objectifs, mais les accomplit correctement à cause de la sémantique des déplacements. Autrement dit, alors qu'il ne peut pas être copié, il peut « déplacer » la propriété:

std::unique_ptr<derived> d(new derived); 

std::unique_ptr<base> b(d); // nope, cannot be copied 
std::unique_ptr<base> b(std::move(d)); // but can be moved 

Cela rend unique_ptr adapté à une utilisation dans des conteneurs, parce qu'ils ne copient plus leurs valeurs, ils les déplacent.

+0

Plus précisément, le constructeur * second * est là pour la conversion implicite (ce qui en fait techniquement pas un constructeur de copie). –

+1

Le premier _is_ est un constructeur de copie valide. Un constructeur de copie peut prendre une référence ou une référence const au type de classe. L'une ou l'autre forme est un constructeur de copie valide. –

+0

@Charles: Ah, j'ai toujours pensé que ça devait être un 'const &', mon erreur. – GManNickG

5

Le premier est un constructeur de copie, puis le second est un constructeur basé sur un modèle de auto_ptr avec d'autres paramètres de modèle.

L'implémentation doit fournir un constructeur de copie non-template s'il ne veut pas que le compilateur soit généré. En effet, un constructeur basé sur un modèle qui pourrait être utilisé comme constructeur de copie ne supprime pas le compilateur en générer un et le compilateur généré serait toujours mieux adapté à la construction de la copie du fait qu'il n'est pas un modèle.

+0

Je ne pense pas que l'OP demande pourquoi un constructeur de copie est nécessaire. Je pense que le PO demande pourquoi il y a deux choses qui ressemblent toutes deux à des constructeurs de copies. – Omnifarious

+0

@Omnifarious: Et c'est exactement ce que ma réponse répond, pourquoi la version non-template doit être fournie même si la version du template semble couvrir toutes les options. –