如何防止派生 class 在 C++ 中成为抽象 class?

How to prevent a derived class being an abstract class in c++?

我有一个关于多态性的问题。以下示例将导致错误 "cannot declare variable ‘obj’ to be of abstract type ‘B’"

我知道问题出在函数 A::foo() 的纯虚方法上,它使 A 成为抽象的 class。此外,class B 是 class A 固有的。如果我没有在 B 的主体中实现方法 foo(),那是否也必然使 B 成为抽象对象?从而导致错误?但这是什么逻辑?可能有很多其他派生的 classes 来自我的基础 class A,函数 foo 可能适用于某些派生的 class,但对于 Class B 可能完全没用. 当然,我可以声明一个空函数 B::foo(),它什么都不做,并使代码成为 运行。但是,对于这种行为有更好的解决方案或解释吗?谢谢!

struct A
{
    A() : x(0)  {}
    virtual int foo() const = 0;   // if I remove this line, code will run with no problem.
    int x;
};

struct B :  A {};

int main()
{
    B obj;
    cout << obj.x << endl;

    return 0;
}

Class A 是抽象的,因为 foo()=0。 如果您从 A 派生,则需要实现此 foo(),否则派生的 class 仍然是抽象的。
所以 class B 必须

int foo() const override {}

能够作为物件使用

您可以将此函数声明为私有的,使其无法访问...但问题是如果 foo() 是否实现 foo() 为什么 B 派生自 A .也许您需要重新考虑您的设计。也许应该将 foo()=0 移动到一个单独的接口 class,并实现多重继承。

Class C : public A, public FooInterface {
public:
    int foo() const override {};
};

或者,您可以实现派生自 A 但添加 foo()AwithFoo class。 IE。添加一些层次结构。

class A {}
class B : public A {}
class AwithFoo : public A {
public:
    using A::A; // a way to inherit the constructor.
    virtual int foo() const = 0;
}
class C : public AwithFoo {
public:
    int foo() const override {};
}

尽管后一种解决方案并不总是好的解决方案。它将添加额外的间接层。

您不应依赖 classed 为您提供不需要的功能。如果你这样做,你就违反了 liskov substitution principle. That`s a bad design and will lead you to many problems such as refused bequest

但是,如果您需要该功能并从基础 class 继承,您必须实现该功能或将其保留为抽象,这将使派生的 class 也抽象。

首先,你是对的,不在 A 中实现 foo 使 A 抽象,不在 B 中实现 foo 使那个抽象还有。

多态的全部意义就是你为一组类提供一个通用的接口。任何派生类型一般都可以作为基本类型,具体行为只会在细节上有所不同(例如,像汽车、自行车或轮船的转向,机制不同,但你 可以 引导他们所有人)。

如果在B上调用foo没有意义,那么先问'Why?'!不知何故,B 不可能是真正的 A 那么,就像螺丝刀不能是锤子一样(但两者都可以是工具)。

如果您遇到这样的麻烦,那么很可能是您的设计存在缺陷。