【问题标题】:using a method declared pure virtual in derived classes [duplicate]在派生类中使用声明为纯虚拟的方法[重复]
【发布时间】:2016-05-04 05:53:50
【问题描述】:

我正在处理一个代码,我看到了一些奇怪的东西,一个“MyClass”类的方法让我们称之为 X():

virtual void X() = 0;

所以 MyClass 是一个抽象类,在 MyClass.cpp X() 中有一个正确的实现...... 在 MyClass 的派生类中,这个方法是通过 MyClass::X(); 调用的;

我认为= 0 会使它的实现无效......但事实并非如此,事实上它可以在派生类中使用。

你能告诉编译器在遇到= 0时到底做了什么吗?

【问题讨论】:

标签: c++ oop virtual derived-class


【解决方案1】:

来自标准(9.2 类成员 [class.mem]):

= 0pure-specifier

它告诉编译器:

  1. 类是抽象的
  2. 方法将被定义在类定义之外 (通常在派生类中)

示例 1(构建失败)

如果我正确理解你的问题,你有类似的东西:

class MyClass {
public:
    virtual void X() = 0;
};

class MyDerivedClass : MyClass {
public:
    virtual void X();
};

void MyDerivedClass::X() { MyClass::X(); }

int main()
{
    MyDerivedClass mdc;
    mdc.X();

    return 0;    
}

如果是这样,构建应该失败:

错误:

undefined reference to 'MyClass::X()'

示例 2(构建成功)

但是,即使方法MyClass::X() 被声明为纯虚拟, 你可以提供一个定义。以下将起作用。班级MyClass 仍然是抽象,不过可以调用方法MyClass::X()

#include <iostream>

class MyClass {
public:
    virtual void X() = 0; // pure virtual method
};

class MyDerivedClass : MyClass {
public:
    virtual void X();
};

void MyClass::X() {       // pure virtual method definition
    std::cout << "MyClass::X()" << std::endl;
}

void MyDerivedClass::X() {
    MyClass::X();
    std::cout << "MyDerivedClass::X()" << std::endl;
}  

int main()
{
    MyDerivedClass mdc;
    mdc.X();

    return 0;    
}

输出:

MyClass::X()
MyDerivedClass::X()

【讨论】:

    【解决方案2】:

    你不能用纯虚方法创建类的实例,但在某些情况下你可以调用纯虚方法,它将是error

    【讨论】:

    • @n.m.如果您提供实现当然会起作用。但通常纯虚方法没有
    • 问题是关于一个有实现的纯虚拟方法。纯虚析构函数必须有一个实现。
    【解决方案3】:

    我认为编译器会为纯虚方法创建一个带有 NULL 指针的 vtable。

    【讨论】:

      【解决方案4】:

      =0 告诉编译器两件事:

      1. 不需要常规的类外函数定义(尽管允许)。如果没有这样的定义,而函数被实际调用,这是一个运行错误。
      2. 该类是抽象的,无法实例化,无论是否存在第 1 点的定义。尝试这样做应该被标记为编译时错误。不覆盖函数的派生类也是抽象的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-01
        • 2017-01-15
        • 1970-01-01
        • 1970-01-01
        • 2013-10-07
        • 1970-01-01
        • 2019-02-07
        相关资源
        最近更新 更多