【问题标题】:Virtual Functions Doubts虚拟功能质疑
【发布时间】:2017-02-12 05:40:12
【问题描述】:

我有这个简单的代码来测试 VF

class A
{
public:
virtual const char Get (){return 'A';}
};

class B : public A
{
public:
const char Get (){return 'B';}
};

class C : public B
{
public:
const char Get (){return 'C';}
};

class D : public C
{
public:
const char Get (){return 'D';}
};

main() 内

D dD;
std::cout<<dD.Get()<<std::endl; //prints D

A & rA = dD;
std::cout<<rA.Get()<<std::endl;//prints D

C cC;

A & rA2 = cC;
std::cout<<rA2.Get()<<std::endl; //print C

B & rB = dD;
std::cout<<rB.Get()<<std::endl;
/*????? it prints D, shouldn't it print B ?????*/

rB指向地址dD,rB只会引用dD对象的对象(B和A)(不会看到C&D)。

当rB.Get()被调用时,它不应该去B中而不是A中的最衍生函数并执行它吗?

【问题讨论】:

  • 为什么你认为派生最多的对象在B中? rB 是对 B 的引用,但派生最多的是 D。请参阅:en.cppreference.com/w/cpp/language/virtual
  • 如果我错了请纠正我,但我认为在 rB 的情况下它指的是对象 dD 的 A&B 部分,并且在调用 rB.Get() 的上下文中,编译器将看A&B中派生最多的Get()就是B::Get()
  • @Adam:是的,你错了。 rB 是对 D 对象的引用。 virtual 函数的全部意义在于静态类型可以是基类,而动态类型是派生的,对于 virtual 函数,调用最派生的动态类型的版本。
  • - 如果 A::Get () 不是虚拟的 - `std::cout
  • 也许你对 B、C 和 D 中的 Get() 方法中缺少 virtual 感到困惑。它们都是虚拟的。将它们标记为虚拟与否没有区别,因为它们的虚拟性是由基类设置的。

标签: c++ class inheritance virtual-functions


【解决方案1】:

当一个函数在类Base 中是虚函数时,它在所有派生类、派生类的派生类等中都是虚函数,无论派生类中是否使用了virtual 这个词。

在您的情况下,这意味着Get 在您的所有课程ABCD 中都是虚拟的。因此,rArB 的案例是相同情况的示例。

返回类型可能略有不同:作为返回类型的原始引用或指针可以在派生类中专门化。由于它的特异性与包含类的方向相同,因此称为协变返回类型。但是,C++ 不支持参数的变化。

【讨论】:

  • 是的 virtual Base 也会使派生函数成为虚拟的,这部分让我很困惑,但现在我明白了。谢谢
猜你喜欢
  • 2014-05-12
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多