To prevent copying a class, you can very easily declare a private copy constructor / assignment operators. But you can also inherit boost::noncopyable
.
What are the advantages / disadvantages of using boost in this case?
boost::noncopyable has private (under C++03) or deleted (under C++11) copy constructor and a copy assignment operator and can't be copied or assigned; a class that derives from it inherits these properties. boost::noncopyable was originally contributed by Dave Abrahams.
class NonCopyable { public: NonCopyable (const NonCopyable &) = delete; NonCopyable & operator = (const NonCopyable &) = delete; protected: NonCopyable () = default; ~NonCopyable () = default; /// Protected non-virtual destructor }; class CantCopy : private NonCopyable {};
It is intended to be used as a private base class. boost::noncopyable has private (under C++03) or deleted (under C++11) copy constructor and a copy assignment operator and can't be copied or assigned; a class that derives from it inherits these properties. boost::noncopyable was originally contributed by Dave Abrahams.
The intent of boost::noncopyable is clearer. Boost::noncopyable prevents the classes methods from accidentally using the private copy constructor. Less code with boost::noncopyable. Show activity on this post. With noncopyable you write the name of your class just once.
In practice, the class can still copy itself. Therefore this method does not get implemented and you will get a linker error. Inheriting from boost::noncopyable will prevent the second use case, however, it also prevents that the compiler can generate a valid default copy constructor ... as they will violate the previous constraints.
The header <boost/core/noncopyable.hpp> defines the class boost::noncopyable. It is intended to be used as a private base class. boost::noncopyable has private (under C++03) or deleted (under C++11) copy constructor and a copy assignment operator and can't be copied or assigned; a class that derives from it inherits these properties.
I see no documentation benefit:
#include <boost/noncopyable.hpp> struct A : private boost::noncopyable { };
vs:
struct A { A(const A&) = delete; A& operator=(const A&) = delete; };
When you add move-only types, I even see the documentation as misleading. The following two examples are not copyable, though they are movable:
#include <boost/noncopyable.hpp> struct A : private boost::noncopyable { A(A&&) = default; A& operator=(A&&) = default; };
vs:
struct A { A(A&&) = default; A& operator=(A&&) = default; };
Under multiple inheritance, there can even be a space penalty:
#include <boost/noncopyable.hpp> struct A : private boost::noncopyable { }; struct B : public A { B(); B(const B&); B& operator=(const B&); }; struct C : public A { }; struct D : public B, public C, private boost::noncopyable { }; #include <iostream> int main() { std::cout << sizeof(D) << '\n'; }
For me this prints out:
3
But this, which I believe to have superior documentation:
struct A { A(const A&) = delete; A& operator=(const A&) = delete; }; struct B : public A { B(); B(const B&); B& operator=(const B&); }; struct C : public A { C(const C&) = delete; C& operator=(const C&) = delete; }; struct D : public B, public C { D(const D&) = delete; D& operator=(const D&) = delete; }; #include <iostream> int main() { std::cout << sizeof(D) << '\n'; }
Outputs:
2
I find it much easier to declare my copy operations than to reason whether or not I'm deriving from boost::non_copyable
multiple times and if that is going to cost me. Especially if I'm not the author of the complete inheritance hierarchy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With