继承纯虚函数

时间:2015-01-15 14:19:46

标签: c++ abstract-class multiple-inheritance pure-virtual

让我们想象以下情况:A是一个定义纯虚函数void f()的抽象类; B是一个实现函数void f()的类; C继承自AB

struct A                     
{                            
    void virtual f() =0;     
};                           

struct B                     
{                            
    virtual void f() { }     
};                           

struct C : public A, public B
{                            
};                           

问题可能是:C是抽象类吗?源自A的抽象要求是子类实现虚函数void f()C不会直接实现它,而是从B继承它。

我已经可以回答这个问题:是的,C是一个抽象类。如果您尝试实例化C类型的对象,您将收到编译错误。所以实际的问题是:为什么C是一个抽象类?

我认为A::fB::f具有相同名称和签名的事实不足以在这些函数之间绘制对应关系,以便B::f实现A::f }。从技术角度来看,我可以看到这些功能"驻留"在C类型的对象的不同部分(虽然我并不确定我的理解是否完整)。但是从概念的角度来看,我可以很容易地想象一个类C想要成为抽象类A的实现的情况,并且为了实现纯虚函数f ,它使用其父类之一的实现。解决方案可能是:

struct C : public A, public B
{
    virtual void f() { B::f(); }
};

,在我的实验中起作用。但这是必要的吗?

修改

进一步的问题:C继承AB的顺序是否相关?如果我写下以下内容会改变什么吗?

struct C : public B, public A
{
};

答案(再次,我测试我的代码,然后我试着提出非平凡的问题)是不,它不会改变任何东西。但在这种情况下(如果我错了,请更正我),C::f如果已实施,则会覆盖B::f,而不是A::f。由于使用A::f对象无法访问C,因此请求实现它是否有意义?

3 个答案:

答案 0 :(得分:1)

C也继承自B,在考虑从A继承的函数时没有什么区别。因此,当编译器发现C没有从A覆盖纯虚拟时,它会使它成为一个抽象类。

答案 1 :(得分:1)

  

源自A的抽象要求是子类实现虚函数

不完全。要求是子类使用非纯函数覆盖纯虚函数。一个基类中的函数不会覆盖另一个基类中的函数; C本身必须声明覆盖是非抽象的。

  

但这是必要的吗?

是。您必须覆盖从A派生的类中的函数;在这种情况下,这意味着C

  

C继承AB的顺序是否相关?

不,声明顺序没什么区别。必须在从A派生的类中声明覆盖。

  

但在这种情况下(如果我错了,请更正我),C::f如果已实施,则会覆盖B::f,而不是A::f

无论基类的声明顺序如何,它都会覆盖两者。

  

由于使用A::f对象无法访问C,因此请求实现它是否有意义?

两者仍然可以访问(虽然名称需要合格,因为不合格的f是不明确的)。仍然需要重写纯函数以使派生类非抽象。

答案 2 :(得分:0)

由于其他答案尚未针对您的新问题进行更新,因此以下是答案。

  

但在这种情况下(如果我错了,纠正我),C :: f,如果实现,将覆盖B :: f,而不是A :: f。

你错了一半。无论继承顺序如何,A::fB::f都会被C::f覆盖。

  

由于使用C对象无法访问A :: f,请求实现它是否有意义?

但使用A::f对象可以访问C 。考虑这一点,相当典型的继承使用:

void call_f(A& a) {
    a.f();
}
int main() {
    C c;
    call_f(c);
}

如果C未覆盖A::f,那么这可能无法正常工作。有意义的是A的具体子类必须实现A::f