xcrypt
xcrypt

Reputation: 3376

avoiding implicit copying with a disabled copy constructor

Suppose you have a class NonCopyable

class NonCopyable
{
public:
   NonCopyable(int n){}
   ~NonCopyable(){}
   [...]

private:
   [members...]

private:
   NonCopyable( const NonCopyable& ); //disabled (no definition)
   NonCopyable& operator= ( const NonCopyable& ); //disabled (no definition)
};

For this class, it's illogical to have copies of it, thus the copy constructor and assignment operator are disabled.

However, when you need a vector of NonCopyables objects:

std::vector<NonCopyable> m_V;
int n;
m_V.push_back(NonCopyable(n));

Here, you implicitly invoke the copy constructor.

I've been taught to solve this problem by using pointers to those objects instead of the objects themselves. But this is annoying both in use and in performance, because you have to dynamically allocate those objects with new()...

My question: Is there a way around this? What's a common solution to this problem?

Upvotes: 2

Views: 403

Answers (2)

Steve Jessop
Steve Jessop

Reputation: 279245

C++11 has a solution that applies to many non-copyable classes: make the class movable (instead of copyable), and use emplace_back to add new elements to the vector.

If you need to fudge something with C++03, perhaps you can find a way to implement copying of "empty" NonCopyable objects (and use Luchian's idea of restricting this operation), and also find a way to implement swap. Then you can do:

std::vector<NonCopyable> m_V;
int n;
m_V.push_back(NonCopyable());
NonCopyable(n).swap(m_V.back());

Upvotes: 4

Luchian Grigore
Luchian Grigore

Reputation: 258568

You can make the vector a friend of the class:

class NonCopyable
{
   friend std::vector<NonCopyable>;
public:
   NonCopyable(int n){}
   ~NonCopyable(){}

private:
   NonCopyable( const NonCopyable& ) {}; 
   NonCopyable& operator= ( const NonCopyable& ) {}; 
};

or you could have a vector of smart pointers to the class.

EDIT:

I might have misunderstood the question. If you don't want copies of the class (my original guess was that you didn't want making copies to be publicly accessible), you should definetely use smart pointers.

Upvotes: 1

Related Questions