【问题标题】:Do C++ abstract classes need to obey the rule of five? [closed]C++ 抽象类是否需要遵守五法则? [关闭]
【发布时间】:2018-11-05 18:39:23
【问题描述】:

当实现这样的抽象类时:

class Base
{
public:
    virtual ~Base() = default;
    virtual void foo() = 0;
};

这个接口是否必须遵守五规则,即我是否必须添加复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符?

我认为Base 类型的实例由于纯虚成员函数而无法实例化,因此为其他特殊成员函数提供默认实现可能没有实际用途。

是否有任何用例/示例需要我提供其他特殊成员函数?

【问题讨论】:

  • 你将如何实现那些构造函数/操作符? :P
  • defaulted 你的析构函数,意味着你告诉编译器生成一个。应该和你什么都不做一样。
  • @KillzoneKid 但我猜其意图是析构函数是虚拟的。
  • @juanchopanza 是的,我的意思是它不应该影响你如何使用三、五等规则。
  • 在这种情况下应该尊重Rule of zero

标签: c++ rule-of-three


【解决方案1】:

“抽象”在这里无关紧要。如果一个类有默认版本无法正确复制的数据,则它需要自己的复制构造函数、复制赋值运算符等。句号。纯虚函数的存在与否不会改变这一点。您的示例没有任何数据,因此这里没有问题。

【讨论】:

  • 保护复制分配是有意义的。这样,任何试图完成任务的人都会被阻止。
  • @Deduplicator — 根据类设计要填充的角色,有许多事情可能重要也可能不重要。抽象不是角色;它是一种工具,它的使用并不意味着对复制的限制。
【解决方案2】:

其实恰恰相反。我会考虑删除应该只是接口类的类的复制和分配,以避免切片。考虑

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

class D1 : public Base {
    int i;
public:
    ~D1() override {}
};

class D2 : public Base {
    int i;
    double d;
public:
    ~D2() override {}
};

你可以这样写

vector<Base> vec;
D1 d;
  D2 e;
  vec.push_back(d);
  vec.push_back(e);

。您会尝试将大小为 D2 的对象压缩到一个更小的 base 类型的对象中。通过删除副本和分配,您确实会阻止用户或您自己这样做。

【讨论】:

  • &gt;&gt;you could write something like this 您的基类不是抽象类,但 OP 是。 D1 d; D2 e; 是不可能的
  • 我很抱歉。这是完全正确的,但它不会使提到的问题无效。
猜你喜欢
  • 2018-10-02
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多