【问题标题】:Rules for deriving from a non-virtual descendant with virtual base class从具有虚拟基类的非虚拟后代派生的规则
【发布时间】:2016-08-13 01:15:28
【问题描述】:

如果我有一个 C++ 类的层次结构,其中基类有一个声明为虚拟的成员函数,但派生类不将该函数声明为虚拟,那么虚拟化在类层次结构中进行了多远。例如,给定的代码是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。

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

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

    从 C++11 开始,您有一个更好的选择:您可以使用 override 标记子类中的虚拟方法,以确保它们实际上覆盖了某些内容。这可以防止由于原型差异很小而实际上不覆盖父方法,并且如果您更改基本虚拟原型但忘记调整覆盖,则会触发错误。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • “技术”是什么意思?在什么其他意义上,最终函数不是虚拟的?
      • “技术上”一词的意思是“具有与...相关的特征”
      • 是的,但这只是说“是”的一种非常模糊的方式:-)
      猜你喜欢
      • 2011-11-16
      • 2016-03-04
      • 2020-10-21
      • 2019-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      • 2013-10-07
      相关资源
      最近更新 更多