Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a derived class be made uncopyable by declaring copy constructor/operator private in base class?

I thought in theory the answer to this question was yes.

However, in practice, my compiler (VS2010) does not seem to complain in the following situation: I have an abstract base class providing some common interface (yet having no data members) and various sub and subsubclasses derived from it.

class Base 
{
public:
    Base() {}
    virtual ~Base() {}

    virtual void interfaceFunction1() = 0;
    virtual void interfaceFunction2() = 0;
private:
    Base(const Base&);            // all derived classes should be uncopyable
    Base& operator=(const Base&);

    // no data members
};

My compiler found it unproblematic to even implement full copy constructors in sub- or subsubclasses.

How can I make sure that every class derived from Base is uncopyable?

edit: If I understand well, this is exactly what Scott Meyers explained in item 6 of Effective C++ (3rd edition, 2005) with his idea of the class Uncopyable (only extended here to a full interface class). What is the difference that makes his idea work ? (I know that he inherits privately, but this should not pose a problem)

like image 946
mr_T Avatar asked Jul 08 '15 09:07

mr_T


2 Answers

This should prevent the compiler from generating a copy constructor for derived classes which do not declare one explicitly. However, nothing prevents a derived class from explicitly declaring a copy constructor which will do something else than call the copy constructor of Base.

There is no way to make sure derived classes are instantiable but not copyable.

like image 171
Angew is no longer proud of SO Avatar answered Oct 20 '22 19:10

Angew is no longer proud of SO


Rather than declaring the copy constructor/operator as private declare them as deleted. Declaring copy constructor/operator as private is not the best solution to making the derived classes non-copyable. If you want the base class to be completely non-copyable then declare the copy constructor/operator as deleted as copy can still take place inside the member functions of Base as private members are accessible to that class's functions. You can use the C++11 feature of delete:

Base(const Base&) = delete; // copy constructor
Base& operator=(const Base&) = delete; // copy-assignment operator

But declaring copy constructor/operator as private is also right as long as you're aware that copy can still take place inside the member functions of Base.

like image 28
Deepam Sarmah Avatar answered Oct 20 '22 17:10

Deepam Sarmah