Percy Flarge
Percy Flarge

Reputation: 437

Why does C++ auto_ptr have two copy constructors and two assignment operators but one default constructor?

Why does it need two forms? Thanks

    explicit auto_ptr (T* ptr = 0) throw() 

    auto_ptr (auto_ptr& rhs) throw() 

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

    auto_ptr& operator= (auto_ptr& rhs) throw()

    template<class Y>
    auto_ptr& operator= (auto_ptr<Y>& rhs) throw()

Upvotes: 7

Views: 803

Answers (4)

peterchen
peterchen

Reputation: 41106

It has one copy constructor - the non-templated one.

The template constructor and assignment operator allow assignment of pointer types for which an implicit exists:

class A {}
class B : public A {}

B * b = new B();
A * a = b;       // OK!


auto_ptr<B> b(new B);
auto_ptr<A> a = b; // *

without the template versions, (*) wouldn't work, as the compiler treats auto_ptr<A> as a completely different type than auto_ptr<B>.

Upvotes: 7

Eclipse
Eclipse

Reputation: 45493

The reason for the non-templated versions is to allow auto_ptrs to the same type to be assigned / constructed. The templated versions exist to allow construction / assignment from related, but not identical pointer types.

auto_ptr <Foo> f = new Foo(); // uses raw pointer constructor
auto_ptr <Foo> f2 = f;  // uses non-templated constructor
auto_ptr <const Foo> f3 = f2; // uses templated constructor   

auto_ptr <Foo> f4 = new foo();
f2 = f4; // uses non-templated assignment operator
f3 = f2; // uses templated assignment operator

Upvotes: 3

Loki Astari
Loki Astari

Reputation: 264411

Why does C++ auto_ptr have two copy constructors and two assignment operators but one default constructor?

It does not.

It has 1 default constructor (a constructor that takes 0 arguments)

explicit auto_ptr (T* ptr = 0) throw() 

It has 1 copy constructor (a constructor that makes a copy from an object of the same type)

auto_ptr (auto_ptr& rhs) throw() 

It has 1 assignment operator that is used to assign objects of the same type.

auto_ptr& operator= (auto_ptr& rhs) throw()

It has a fancy templated constructor that takes auto_ptr of other types (this is not a copy constructor it is just a normal constructor (though it is templated)).

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

It has another assignment operator that takes different types of auto pointer (So yes this is another assignment operator but it is not a copy assignment operator (but a conversion assignment operator) as the rhs has a different type).

template<class Y>
auto_ptr& operator= (auto_ptr<Y>& rhs) throw()

Upvotes: 4

Edward Strange
Edward Strange

Reputation: 40859

Because copy constructors cannot be templates. If they only had the template version then the compiler would make one that would not work correctly.

Same for assignment op...I think.

Upvotes: 6

Related Questions