Search code examples
c++inheritancemultiple-inheritance

How to delete constructors and operators using inheritance in c++?


Suppose I have two classes, no_copy and no_move which are base classes. From which any class can derive from and hence have their constructors and operators modified.

As the name suggests, no_copy will literally just do the following; (commented out what it should do)

class base : no_copy
{
    /*
       base(const base&)=delete;
       base& operator=(const base&)=delete;
    */
};

And the same for no_move,

class base : no_move
{
    /*
       base(base&&)=delete;
       base& operator=(base&&)=delete;
    */
};

These classes (no_copy & no_move) make it so that the class that derives from it should not be copyable or moveable.

Right now I am just using a macro to do this;

// For classes without a qualified name
#define __NO_COPY__(__class__) __class__::__class__(const __class__&)=delete; __class__& __class__::operator=(const __class__&)=delete;

// For classes with qualified names
#define __NO_COPY_LIB__(__qualified_name__,__class__) __qualified_name__::__class__(const __class__&)=delete; __class__& __qualified_name__::operator=(const __class__&)=delete;

And the same technique for not moving.


EDIT: Examples of the macros;

suppose a class as such;

namespace wrapper
{
   class my_class {};

   __NO_COPY__(my_class);
}
__NO_COPY_LIB__(::wrapper::my_class,my_class);

The macros work just fine, but it doesn't look pretty. Moreover they are not easy to refactor as these macros can be anywhere in the definition or implementation.

A syntax like the following would mean that all of this in right there in the definition of the class and can be changed or modified very easily;

class base : public attributes<no_copy,no_move> {};

The attributes struct is just defined as;

template <typename... _BCs/*Base Classes*/>
struct attibutes : public _BCs... {};

Now obviously the syntax of inheriting doesn't matter that much. All I want it to be able to define where the class can be copied,moved or not. Also, if there is a method other than inheritance which could work please do suggest it.

As all I am looking for is the method that is easily refactorable.


I have tried finding solutions online about how to overload constructors. But so far I have not found anything about deleting them and hence I am doubting if it is even possible to delete constructors or operators using inheritance.

Any help would be greatly appreciated.


Solution

  • Special member functions delegate to the corresponding functions of their subobjects (bases and members) and will be defaulted as deleted if that delegation finds a deleted or inaccessible function.

    Although you could use a non-static member for this, using a base class is better because it enables the "Empty Base Optimization", not costing anything.

    struct no_copy
    {
    protected:
        no_copy() = default;
        no_copy(const no_copy&) = delete;
        no_copy& operator=(const no_copy&) = delete;
    };
    
    class important_class : no_copy {};
    

    pre-C++11 version:

    class no_copy // members default to "private"
    {
        no_copy(const no_copy&); // no definition needed
        no_copy& operator=(const no_copy&); // no definition needed
    protected:
        no_copy() {}
    };
    

    This won't stop the derived class from defining a user-provided special member that explicitly avoids calling the base class version, but if you do that it shows intent to make the derived class actually be copyable/whatever after all.