53

When I'm writing a class (say class nocopy), is it possible to prevent the existence of the copy operator entirely? If I don't define one, and somebody else writes something like

nocopy A;
nocopy B;
A = B;

the compiler will auto-generate a definition. If I define one myself, I will prevent the compiler from auto-generating, but the code above will still be legal.

I want the code above to be illegal, and generate a compile time error. How do I do that?

Malabarba
  • 4,473
  • 2
  • 30
  • 49

3 Answers3

89

You just declare a copy constructor with private access specifier and not even define it.
Anyone trying to use it will get an compile error since it is declared private.

If someone uses it even indirectly, you will get a link error.

You can't do anything more than that in C++03.

However, In C++11 you can Explicitly delete special member functions.

Eg:

struct NonCopyable {
    NonCopyable & operator=(const NonCopyable&) = delete;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable() = default;
};
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 4
    One step further is to inherit `boost::noncopyable` – tenfour Oct 19 '11 at 15:36
  • For Windows, see: [Explicitly Defaulted and Deleted Functions](https://msdn.microsoft.com/en-us/library/dn457344.aspx) And the C++11 support matrix for VS2010-VS2013 [Support For C++11 Features (Modern C++)](https://msdn.microsoft.com/en-us/library/hh567368.aspx) – bvj Mar 29 '15 at 21:29
  • can i also static_assert that it has been deleted? – Janus Troelsen Jun 26 '17 at 15:38
  • 1
    @JanusTroelsen yes, with `std::is_copy_assignable` from `` – dkg Aug 10 '17 at 14:38
  • Are you saying it is enough to declare the copy ctor private, to disable the compiler-generated assignment operator? – Firstrock Mar 02 '18 at 13:12
6

The usual way is to declare the copy constructor and the assignment operator to be private, which causes compilation errors, like Als explained.

Deriving from boost::noncopyable will do this job for you.

thiton
  • 35,651
  • 4
  • 70
  • 100
4

If you inherit from boost::noncopyable you will get a compile time error when the copy constructor is attempted. I have found that using this the error messages (with MSVC) are useless, since they generally don't point to the line that caused the error. The alternative is to declare a copy-constructor private and leave it undefined, or define it with a BOOST_STATIC_ASSERT(false). If you are working with C++11 you can also delete your copy constructor:

class nocopy
{
    nocopy( nocopy const& ) = delete;
};
K-ballo
  • 80,396
  • 20
  • 159
  • 169