Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

c++ - Is deleting copy and move constructors/assignment operators in base class enough?

If I have an abstract base class and I want to make all derived classes noncopyable and nonmovable is it sufficient to declare these special member functions deleted in the base class? I want to ensure that my entire class hierarchy is noncopyable and nonmovable and am wondering if I can get away with not having to declare those 4 special member functions as deleted in every derived class. I saw a SO answer where it seemed to imply that a derived class could explicitly declare a copy or move constructor despite being deleted from the base class but the following example results in a compilation error when I try to define a defaulted copy assignment operator so I'm unsure. This is the error:

derived_class.cc:15:15: error: defaulting this copy constructor would delete it after its first declaration DerivedClass::DerivedClass(const DerivedClass &) = default;

derived_class.h:9:22: note: copy constructor of 'DerivedClass' is implicitly deleted because base class 'virtual_functions::BaseClass' has a deleted copy constructor class DerivedClass : public BaseClass {

base_class.h:11:3: note: 'BaseClass' has been explicitly marked deleted here BaseClass(const BaseClass &) = delete;

// base_class.h
class BaseClass {
public:
  BaseClass(const BaseClass &) = delete;
  BaseClass(BaseClass &&) = delete;
  BaseClass &operator=(const BaseClass &) = delete;
  BaseClass &operator=(BaseClass &&) = delete;
  virtual ~BaseClass() = default;
  virtual bool doSomething() = 0;

protected:
  BaseClass(std::string name);

private:
  std::string name_;
};

// derived_class.h
class DerivedClass : public BaseClass {
public:
  DerivedClass();
  DerivedClass(const DerivedClass &);
  bool doSomething() override;
};

// derived_class.cc
DerivedClass::DerivedClass(const DerivedClass &) = default;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You cannot prevent a child class from defining its own copy/move constructor. That said, it will prevent it "out of the box", meaning if you do not provide one, or use a inline default constructor, it will also be marked as deleted. The reason you get a error here when you try to just define the constructor as default is because you are not allowed to do that in an out of line definition when a member or base has implicitly deleted it. Had you used

class DerivedClass : public BaseClass {
public:
  DerivedClass(const DerivedClass &) = default;
  bool doSomething() override;
};

then the code would compile, and you would only get an error if you actually try to call the copy constructor. This works because an inline implicit default is allowed even when a member or base implicitly deletes it and the end result is the constructor is implicitly deleted.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...