Can a derived class be made uncopyable by declarin

2019-04-26 15:00发布

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)

3条回答
Evening l夕情丶
2楼-- · 2019-04-26 15:46

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.

查看更多
SAY GOODBYE
3楼-- · 2019-04-26 15:54

In C++11 and later there is the option to declare a constructor deleted.

struct X {
  X( const X& ) = delete;
};

Now, anything derived from X that rely on the copy-constructor will not compile. This is most useful when you want to avoid problems because the compiler auto-generates constructors...

查看更多
何必那么认真
4楼-- · 2019-04-26 15:58

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.

查看更多
登录 后发表回答