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):
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:
- Log files
- Some mutices
- In Singleton pattern
- Object Factory
- 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
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.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 inheritingboost::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
Fatal Error Lnk1104: Cannot Open File 'Libboost_System-Vc110-Mt-Gd-1_51.Lib'
Source Code of C/C++ Functions
Does "Std::Size_T" Make Sense in C++
Why Destructor Is Not Called on Exception
Calculating the Amount of Combinations
Creating a Zip File on Windows (Xp/2003) in C/C++
Must the Int Main() Function Return a Value in All Compilers
How to Directly Bind a Member Function to an Std::Function in Visual Studio 11
Link Errors Using <Filesystem> Members in C++17
How to Read Entire Stream into a Std::String
Converting Data from Glreadpixels() to Opencv::Mat
Segmentation Fault at Glgenvertexarrays( 1, &Vao );
Converting Std::String to Std::Vector<Char>