Disable Copy Constructor

Disable copy constructor

You can make the copy constructor private and provide no implementation:

private:
SymbolIndexer(const SymbolIndexer&);

Or in C++11, explicitly forbid it:

SymbolIndexer(const SymbolIndexer&) = delete;

Most concise way to disable copy and move semantics

According to this chart (by Howard Hinnant):

meow

The most concise way is to =delete move assignment operator (or move constructor, but it can cause problems mentioned in comments).

Though, in my opinion the most readable way is to =delete both copy constructor and copy assignment operator.

Conditionally disabling a copy constructor

A noteworthy approach is partial specialization of the surrounding class template.

template <typename T,
bool = std::is_copy_constructible<T>::value>
struct Foo
{
T t;

Foo() { /* ... */ }
Foo(Foo const& other) : t(other.t) { /* ... */ }
};

template <typename T>
struct Foo<T, false> : Foo<T, true>
{
using Foo<T, true>::Foo;

// Now delete the copy constructor for this specialization:
Foo(Foo const&) = delete;

// These definitions adapt to what is provided in Foo<T, true>:
Foo(Foo&&) = default;
Foo& operator=(Foo&&) = default;
Foo& operator=(Foo const&) = default;
};

This way the trait is_copy_constructible is satisfied exactly where T is_copy_constructible.

Deleting copy constructors and copy assignment operators. Which of them are essential?

You only need to mark a single copy constructor and copy assignment operator as delete. The presence of the copy versions will prevent the implicit-declaration of the move constructor and move assignment operator, and declaring one form of a copy special member function suppresses the implicit-declaration of other forms.

MyClass (const MyClass&) = delete;
MyClass& operator= (const MyClass&) = delete;

Note that post-C++11, implicit-definition of the assignment operator as defaulted is deprecated and it should instead be defined as deleted.

in which case we need to disable default copy constructor and assign operator?

When you want the objects of this class to be non-copyable.

There may be many reasons when objects can't be or shouldn't be copied to other objects. A few examples are:

  1. Log files
  2. Some mutices
  3. In Singleton pattern
  4. Object Factory
  5. Some versions of smart pointers

For above examples, compiler provided version of default copy constructor and default assignment operators may lead to unexpected results.

c++11 onwarnds, you can use =delete syntax to delete the compiler provided default versions.

Another use is to force (restrict) copying of objects only via class utilities virtual Base* clone() for example.

Related: Rule of three or rule of five

Most concise way to disable copying class in C++11

  1. Only copy constructor and copy assignment operator will be generated when destructor is explicitly defaulted. And even then their generation is deprecated. So, in order to have virtual destructor and all default methods, one should write the following:

    struct Base
    {
    Base()=default;
    virtual ~Base() = default;
    Base(const Base&)=default;
    Base& operator=(const Base&)=default;
    Base(Base&&)=default;
    Base& operator=(Base&&)=default;
    };

    I would definitely use a macro for more than one such Base class.

  2. In case when destructor is defined by user, 2 special methods are still generated. There are the following ways to disable deprecated generating copy constructor and copy assignment operator:

    • delete move constructor OR move assignment operator (not quite self-explanatory but very short):

      Base(Base&&)=delete; // shorter than deleting assignment operator
    • delete both copy constructor and copy assignment operator:

      Base(const Base&)=delete;
      Base& operator=(const Base&)=delete;

    Note that you have to explicitly declare default constructor if you need it, e.g. Base()=default;.

    Macro or inheriting special class can be used as well for this purpose but I personally prefer deleting move constructor to implementing my own macro or base class. When using Qt or boost, I would prefer Q_DISABLE_COPY(Base) and inheriting boost::noncopyable respectively, because they are already implemented, widely known and recognizable.

http://accu.org/index.php/journals/1896 - detailed explanation and rationale for these issues.

Is there a way to disable copy elision in c++ compiler

Pre C++ 17

A a3 = 0;

will call copy constructor unless copy is elided. Pass -fno-elide-constructors flag

from C++17, copy elision is guaranteed. So you will not see copy constructor getting called.

Disable copy/assignment, automatically disabled for children?

Yes, this also inhibits implicit copying of child classes. In fact that's how inheriting from boost::noncopyable (http://www.boost.org/doc/libs/master/libs/core/doc/html/core/noncopyable.html) works. However someone could always write their own copy constructor/copy assignment for the child class that doesn't actually copy the Foo component, or copies it in a different way.



Related Topics



Leave a reply



Submit