C++ 抽象类需要遵守五法则吗?[已结束]

Do C++ abstract classes need to obey the rule of five? [closed]

提问人:Markus Rothe 提问时间:5/27/2018 更新时间:5/27/2018 访问量:2425

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

5年前关闭。

当实现这样的抽象类时:

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

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

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

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

C++ 三法则

评论

2赞 Rakete1111 5/27/2018
您将如何实现这些构造函数/运算符?:P
0赞 Killzone Kid 5/27/2018
你编辑了析构函数,意味着你告诉编译器生成一个析构函数。这应该和你什么都不做没有什么不同。default
1赞 juanchopanza 5/27/2018
@KillzoneKid 但我想其目的是析构函数是虚拟的。
1赞 Killzone Kid 5/27/2018
@juanchopanza 是的,我的意思是它不应该影响你如何使用三、五等规则。
1赞 Marek R 5/27/2018
在这种情况下,应该得到尊重。Rule of zero

答:

0赞 martinsteih 5/27/2018 #1

实际上恰恰相反。我会考虑删除一个应该只是一个接口类的复制和赋值,以避免切片。考虑

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 类型的对象中。通过删除副本和分配,您可以阻止用户或您自己这样做。

评论

0赞 Killzone Kid 5/27/2018
>>you could write something like this你的基类不是一个抽象类,但OP的基类是一个抽象类。 是不可能的D1 d; D2 e;
0赞 martinsteih 5/27/2018
我道歉。这是非常正确的,但它并没有使提到的问题无效。
1赞 Pete Becker 5/27/2018 #2

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

评论

0赞 Deduplicator 5/27/2018
不过,保护复制分配是有意义的。这样,任何试图完成任务的人都将被阻止。
2赞 Pete Becker 5/27/2018
@Deduplicator — 有很多事情可能重要,也可能不重要,这取决于一个类被设计来填补的角色。抽象不是一种角色;它是一种工具,它的使用绝不意味着对复制的限制。