views:

95

answers:

3

If I have a class

template <typename T>
struct C {
...

private:
  auto_ptr<T> ptr;
};

How do I define the copy constructor for C:

It cannot be

template <typename T>
C<T>::C(const C& other) 

because I want to if I copy the auto_ptr from other, I have changed other by removing ownership. Is it legal to define a copy constructor as

template <typename T>
C<T>::C(C& other) {}
+1  A: 

If you want to prevent transfer of ownership and/or copying, you can define the copy constructor and assignment operator private, thereby forbidding users of your class from ever copying or assigning your object.

zdawg
+1  A: 

Do you actually want to copy your class's state or transfer it? If you want to copy it then you do it just like any other class with pointers in it:

template < typename T >
C<T>::C(C const& other) : ptr(new T(*other.ptr)) {} // or maybe other.ptr->clone()

If you actually want to transfer ownership of the pointer you could do it with a non-const "copy" constructor but I'd recommend you do something that's more obvious at the call site; something that tells people reading the code that ownership has transfered.

Noah Roberts
If he wants to transfer he doesn't need to do anything at all. The compiler provides the correct copy constructor automatically in that case - although i would recommend against that too.
Johannes Schaub - litb
Interesting. I was sure you were wrong but it appears that the compiler will then create a non-const constructor for C automatically. I'll have to look into the rules that make that happen. At any rate, I still stand by my advice to use something more obvious.
Noah Roberts
A: 

There's no such thing as a "standard" copy constructor, but people do expect them to behave a certain way. If your object is going to do any transferring of ownership on copy, then it's a bad idea to make a copy constructor that obscures this fact. A better approach would be to create a method that makes this clear. (You could call it CloneAndTransfer or something similar.)

Peter Ruderman