在基类中删除复制和移动构造函数/赋值运算符是否足够? [英] Is deleting copy and move constructors/assignment operators in base class enough?

查看:220
本文介绍了在基类中删除复制和移动构造函数/赋值运算符是否足够?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个抽象基类,并且想使所有派生类不可复制且不可移动,那么声明在基类中删除的这些特殊成员函数就足够了吗?我想确保我的整个类层次结构是不可复制和不可移动的,并且想知道是否可以不必在每个派生类中将这4个特殊成员函数声明为已删除.我看到一个SO答案,似乎暗示着派生类尽管已从基类中删除了,但仍可以显式声明副本或移动构造函数,但以下示例在尝试定义默认的副本赋值运算符时导致编译错误,因此我不确定.这是错误:

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:错误:默认情况下,此副本构造函数将在第一次声明后将其删除 DerivedClass :: DerivedClass(const DerivedClass&)=默认值;

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:注意:'DerivedClass'的副本构造函数被隐式删除,因为基类'virtual_functions :: BaseClass'具有已删除的副本构造函数 class DerivedClass:公共BaseClass {

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:注意:"BaseClass"已在此处明确标记为已删除 BaseClass(const BaseClass&)= delete;

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;

推荐答案

您不能阻止子类定义其自己的复制/移动构造函数.就是说,这将防止它开箱即用",这意味着,如果您不提供它,或者使用内联默认构造函数,它也将被标记为已删除.当您尝试仅将构造函数定义为默认值时,在此出现错误的原因是,当成员或基础隐式删除它时,不允许在离线定义中执行此操作.你曾经用过

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.

这篇关于在基类中删除复制和移动构造函数/赋值运算符是否足够?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆