c++ - 创建没有虚拟纯方法 C++ 的抽象类时出现问题

标签 c++ class polymorphism

我想创建一个类,该类是具有公共(public)虚拟基类的两个类的子类。此外,我希望这个类是抽象的(无法创建它的实例,但也不需要调用虚拟基类的构造函数)。

示例代码:

#include <cstdio>
class CommonBaseClass {
public:
    virtual void DoSomething() = 0;
    virtual void DoSomethingElse() = 0;

    CommonBaseClass(int a) {}
};

class ClassA : public virtual CommonBaseClass {
public:
    virtual void DoSomething() override {
        printf("SOMETHING\n");
    }
    ClassA() {};
};

class ClassB : public virtual CommonBaseClass {
public:
    virtual void DoSomethingElse() override {
        printf("SOMETHING ELSE\n");
    }
    ClassB() {};
};

class TargetClass : //I will never instantiate this class
    public ClassA,
    public ClassB
{
public:
    TargetClass() : ClassA(), ClassB() {} //I don't want to call the CommonBaseClass ctor
};

class SubclassOfTarget :
    public TargetClass
{
public:
    SubclassOfTarget(int a) : CommonBaseClass(a), TargetClass()
    {}
};

int main()
{
    SubclassOfTarget c(15);
    c.DoSomething();
    c.DoSomethingElse();
}

如果您尝试编译此程序,您将看到编译器提示 TargetClass 未调用 CommonBaseClass 的构造函数。

最佳答案

确实(自 C++11 起)抽象类的构造函数不需要初始化其虚拟基类。使类抽象而没有任何特定的未实现的虚函数的通常方法是使析构函数成为纯虚函数。

通过此更改,您的程序可以编译:

class TargetClass : //I will never instantiate this class
    public ClassA,
    public ClassB
{
public:
    TargetClass() : ClassA(), ClassB() {} //I don't want to call the CommonBaseClass ctor

    virtual ~TargetClass() = 0;
};
TargetClass::~TargetClass() = default;

请注意,必须定义析构函数,即使它是纯析构函数。由于一个声明不能同时具有 = 0{body}= default,因此析构函数定义在这种情况下需要在类定义之外。

尽管实际上,建议始终确保任何多态类(至少有一个虚拟函数或虚拟基类)都有一个虚拟析构函数。这使得删除指向具有不同动态类型的对象的基类类型指针是合法的。使用通常的 vtable 实现,将虚拟析构函数添加到已经是多态的类中几乎不需要任何成本。按照此建议,您还可以将 virtual ~CommonBaseClass() = default; 添加到 CommonBaseClass,然后其他类也自动具有虚拟析构函数。然后您可以使用 ~TargetClass() override = 0; 样式来声明纯虚拟析构函数。

关于c++ - 创建没有虚拟纯方法 C++ 的抽象类时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72757374/

相关文章:

C#:错误-无法将类型 'int' 隐式转换为 'System.Collections.Generic.IEnumerable<double>'

c++ - 推导过程中形成的未命名对象

c++ - 为什么我的银行管理系统不能正常工作?

java - secret 可以隐藏在提供访问凭证的 'safe' java 类中吗?

java - Java 中泛型集合的多态性

c++ - 私有(private)继承中的对象切片

c++ - 可以优化 lambda 按值捕获吗?

c# - 初始化查找<int, string>

java - 避免 instanceof 和 cast,一个 Super Class 可以知道 children 类吗?

c++ - 从多态指针检查类成员是否存在?