Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

privately or publicly inherit from boost::non_copyable?

Which practice would you recommend, and why?

class Foo : public boost::noncopyable {};

vs.

class Foo : private boost::noncopyable {};

I can't imagine needing to use an instance of Foo as a boost::noncopyable, so I'm leaning toward private inheritance in this case.

like image 560
tmatth Avatar asked Apr 13 '11 19:04

tmatth


People also ask

What is boost :: 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.

How do you make a non copyable object?

Solution and Sample CodeEdit 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 {};


3 Answers

boost::noncopyable does not declare a virtual destructor, i.e. is not designed to be the base of public inheritance chain. Always inherit from it privately.

like image 113
Nikolai Fetissov Avatar answered Sep 29 '22 19:09

Nikolai Fetissov


I think that from higher point of view it should be public inheritance. The reasons to make it private are purely technical.

Why? Because whether a type is copyable or not (and this is shown by inheriting from boost::noncopyable) is part of public interface. For example if the inheritance would be public you would be able to check (using "meta programming") whether type derives from boost::noncopyable and then reason about whether it is copyable or not.

Nikolai N Fetissov in his answer to this question points out that boost::noncopyable doesn't have virtual destructor and so should not be used as public base class. While that it a valid argument in general I think it is so unlikely that anyone ever would try to use (and delete in particular) an object by a pointer to boost::noncopyable that it makes the argument (in this particular case) purely academic.

Come on! If someone is so inclined to misuse code that he uses delete on a pointer to boost::noncopyable then there is no way to be safe. Sure you can make it a bit harder but a programmer so determined will find some other way to misuse code anyway.

Also it seems that in C++11 boost::noncopyable could solve that issue by declaring default protected destructor:

protected:
    ~noncopyable() = default;

This way there should be no additional cost of declaring destructor (since we made it default) while we are protected from delete on a pointer to boost::noncopyable.

On the other hand however it also seems unlikely that anyone will be willing to check whether a type is copyable by checking inheritance from boost::noncopyable. Mostly because it doesn't provide complete answer. Just because a type doesn't derive from boost::noncopyable it doesn't mean that it is copyable.

Note also that Boost.Noncopyable docs suggest use of private inheritance.

like image 26
Adam Badura Avatar answered Sep 27 '22 19:09

Adam Badura


According to the Boost document

It is intended to be used as a private base.

like image 45
Michael Ma Avatar answered Sep 26 '22 19:09

Michael Ma