5

I have a base class, and I do not want to make derived class copyable. In order to make everything explicit I implement it in that way:

class A {                                                                     
public:    
    A() = default;                                                                   
    virtual ~A() = default;                                                   
    A(const A&)  = delete;                                                    
    A(const A&&) = delete;                                                    
    A& operator=(const A&)  = delete;                                         
    A& operator=(const A&&) = delete;                                         

    virtual void vFun() = 0;                                                  
};                                                                            

class B : public A {                                                          
public:
    B() = default;                                                                       
    virtual ~B() = default;                                                   
    B(const B&)  = delete;                                                    
    B(const B&&) = delete;                                                    
    B& operator=(const B&)  = delete;                                         
    B& operator=(const B&&) = delete;                                         

    virtual void vFun() override {}                                           
};

Is this correct way of doing such things? According to my knowledge and what I have read, the answer is yes, but I would like to be sure before I introduce it into production system.


EDIT

Taking things into conclusion: 1) Almost always move operators should not be deleted. That's because "there's an infinity of things that require movability". 2) For abstract base class, it's safer to allow compiler to generate special member function, and move deletion into derived class if such necessity exists.

galvanize
  • 537
  • 1
  • 5
  • 17
  • 4
    The move constructors should take `A &&` rather than `const A &&`. – The Paramagnetic Croissant Sep 13 '15 at 10:21
  • 2
    You have also deleted the move constructor and move assigner, did you mean to make the class _unmovable_ in addition to being uncopyable? Btw `const T&&` [is probably not what you want](http://stackoverflow.com/q/4938875/3425536). – Emil Laine Sep 13 '15 at 10:21
  • 1
    You don't want to make derived class copyable, but.. then you delete the *move* operators? – Puppy Sep 13 '15 at 10:23
  • Right, I removed const and, after wondering for a while, default move constructor makes sense. – galvanize Sep 13 '15 at 10:26
  • @galvanize Please don't edit your question like that - it invalidates answers. – Barry Sep 13 '15 at 10:37
  • 1
    1) Don't completely re-edit the question when answers are posted 2) Without knowing if your class deals with ownership and/or what it is supposed to do it's hard to answer objectively and only observations can be posted – Marco A. Sep 13 '15 at 10:50

1 Answers1

6

Nope, this is completely incorrect.

Firstly, in your quest to make the derived class noncopyable, you have made it non-movable, which renders it nearly useless.

Secondly, there's no reason for A to be noncopyable at all. Each derived class can just make itself noncopyable if it wants to. A is already abstract and cannot be sliced so there's no reason to make A noncopyable.

Puppy
  • 144,682
  • 38
  • 256
  • 465