从具有虚拟基类的非虚拟后代派生的规则

时间:2016-04-20 11:30:09

标签: c++ inheritance

如果我有一个C ++类的层次结构,其中基类具有声明为virtual的成员函数,但派生类不会将该函数声明为虚拟,那么虚拟化所带来的类层次结构有多远。例如,给定代码是MyFunc2的返回值,定义良好?

class A
{
public:
  virtual int x() { return 1; }
}

class B : public A
{
public:
  int x() { return 2; }
};

class C: public B
{
public:
  int x() { return 3; }
};

int MyFunc1(f &A)
{
 return f.x();  
}

int MyFunc2(f &B)
{
 return f.x();
}

int MyFunc3()
{
 C c;
 return MyFunc1(c);
}

int MyFunc4()
{
 C c;
 return MyFunc2(c);
}

similar question here开始,一旦虚拟特征在基类中是虚拟的,它似乎会向前传播到所有类,但我想知道它是如何定义的,特别是Bx()虚拟特征来自A的含义。

2 个答案:

答案 0 :(得分:4)

子类中的覆盖也是隐式虚拟的。您可以再次指定virtual关键字,但它没有任何区别,尽管它通常被视为良好做法。绝对是#34;定义明确"在标准中。

启动C ++ 11,您有一个更好的选择:您可以使用override标记子类中的虚拟方法,以确保它们实际覆盖某些内容。这可以防止实际覆盖父方法,因为原型差异较小,如果更改基本虚拟原型但会忘记调整覆盖,则会触发错误。

答案 1 :(得分:1)

是的,virtual特征是“传播”(使用您的措辞)到所有派生类。如果派生类声明并定义了一个与继承的虚函数具有相同签名的成员函数,则它们会覆盖它。

C ++ 11引入了final修饰符,派生类可以使用它来防止其后代进一步覆盖继承的虚函数。但是,该函数在技术上仍然是虚拟的(例如,给定指向base的指针,p->func()的多态调用调用对应于对象的实际类型的func() ....它只是不能被覆盖