Disable copy constructor

C++Copy Constructor

C++ Problem Overview


I have a class :

class SymbolIndexer {
protected:
  SymbolIndexer ( ) { }

public:
  static inline SymbolIndexer & GetUniqueInstance ( ) 
  { 
    static SymbolIndexer uniqueinstance_ ;
    return uniqueinstance_ ; 
  }
};

How should I modify it to disable code like:

SymbolIndexer symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

and only allow code like :

SymbolIndexer & ref_symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

C++ Solutions


Solution 1 - C++

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;

Solution 2 - C++

If you don't mind multiple inheritance (it is not that bad, after all), you may write simple class with private copy constructor and assignment operator and additionally subclass it:

class NonAssignable {
private:
    NonAssignable(NonAssignable const&);
    NonAssignable& operator=(NonAssignable const&);
public:
    NonAssignable() {}
};

class SymbolIndexer: public Indexer, public NonAssignable {
};

For GCC this gives the following error message:

test.h: In copy constructor ‘SymbolIndexer::SymbolIndexer(const SymbolIndexer&)’:
test.h: error: ‘NonAssignable::NonAssignable(const NonAssignable&)’ is private

I'm not very sure for this to work in every compiler, though. There is a related question, but with no answer yet.

UPD:

In C++11 you may also write NonAssignable class as follows:

class NonAssignable {
public:
    NonAssignable(NonAssignable const&) = delete;
    NonAssignable& operator=(NonAssignable const&) = delete;
    NonAssignable() {}
};

The delete keyword prevents members from being default-constructed, so they cannot be used further in a derived class's default-constructed members. Trying to assign gives the following error in GCC:

test.cpp: error: use of deleted function
          ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
test.cpp: note: ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
          is implicitly deleted because the default definition would
          be ill-formed:

UPD:

Boost already has a class just for the same purpose, I guess it's even implemented in similar way. The class is called boost::noncopyable and is meant to be used as in the following:

#include <boost/core/noncopyable.hpp>

class SymbolIndexer: public Indexer, private boost::noncopyable {
};

I'd recommend sticking to the Boost's solution if your project policy allows it. See also another boost::noncopyable-related question for more information.

Solution 3 - C++

Make SymbolIndexer( const SymbolIndexer& ) private. If you're assigning to a reference, you're not copying.

Solution 4 - C++

C++ developers learning about reference vs pointer may be tempted to have

class MyClass {
    SomeClass acc;
public:
    MyClass() : acc() {}
    SomeClass &GetAccess( return acc; );
};

As a convenient way to then do:

someblock->{
    MyClass inst;
    auto acc = inst.GetAccess();  


    acc.SomeFunction();
}

which will create problems with double frees inside of SomeClass, because you end up with a copy by default...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHumble DebuggerView Question on Stackoverflow
Solution 1 - C++R. Martinho FernandesView Answer on Stackoverflow
Solution 2 - C++firegurafikuView Answer on Stackoverflow
Solution 3 - C++Aaron KlotzView Answer on Stackoverflow
Solution 4 - C++GrwwwView Answer on Stackoverflow