【问题标题】:Pure virtual method must be implemented only in immediate derived classes - why?纯虚方法只能在直接派生类中实现——为什么?
【发布时间】:2015-01-07 15:02:07
【问题描述】:

假设有一个抽象类A和两个类BC分别派生自AB

class A
{
    virtual void print() = 0;
};

class B : public A
{
    void print(); 
};

//print() must be implemented
void B::print()
{
    std::cout << "Hello" << std::endl;
}

class C : public B
{
    //print() does not require to be implemented
};

我了解到,从C 的直接父级B 的角度来看,print() 不是纯虚方法,但从C 的祖父级A 的角度来看,print() 是纯虚方法。那么,它不应该也需要在C 中实现吗?

【问题讨论】:

  • 为什么C 应该关心B 如何提供它所有的好处?并且纯虚函数不需要在派生类中实现。它们只需要在某个地方实现,派生类就没有纯虚函数,因此是不可实例化的。
  • C 从 B 继承了它的实现,所以它不必提供一个。但是,B 没有从 A 那里得到一个,因为它是纯虚拟的。
  • 不知道你说的这两个“观点”是什么意思。该函数有一个非纯覆盖,所以一切都很好。只要覆盖存在,该覆盖在层次结构中的确切位置并不重要。
  • @Borgleader: B 可以A 得到一个,即使 A 标记了纯虚拟函数。这在 dtor 中最为常见……
  • @Deduplicator 我指的是这个具体案例。在这种情况下,它不会。

标签: c++ class derived-class pure-virtual


【解决方案1】:

C 并不“关心”它如何获得一个实现,只是它得到一个。它从B 得到一个。但是B 没有收到print 的实现,因此需要自己实现print

编辑:根据下面的 cmets,不得再次将实现标记为纯虚拟

【讨论】:

  • 仅仅获得一个实现是不够的。实施者不得将其标记为纯虚拟(再次)。
  • @Deduplicator 您不能提供纯虚拟的实现,声明您提供了一个实现就足够了,可以暗示它不是纯虚拟的事实,因此 sedavidw 的声明是完整且非冗余,你只是在吹毛求疵
  • @Zadirion:“你不能提供纯虚拟的实现……”?试试吧,效果很好。
  • @Deduplicator 适当地编辑了问题
【解决方案2】:

您需要为所有使用 ODR 的东西定义一个定义,并且虚函数总是由类(vtable)使用 ODR。

当然,除非它们被标记为纯虚拟。

一个类是抽象的,因此不能被实例化,如果它至少有一个纯虚拟成员。
该成员是否被继承并不重要,但继承只是直接来自基类。

纯虚拟并不排除实际定义,允许非虚拟调用。

【讨论】:

    猜你喜欢
    • 2018-10-14
    • 1970-01-01
    • 2018-02-27
    • 2019-02-07
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    相关资源
    最近更新 更多