【问题标题】:virtual function in inhertiance hierarchy继承层次结构中的虚函数
【发布时间】:2014-01-06 16:57:46
【问题描述】:

当我有这样的东西时,当我有a* mya=new c(); 并调用a->displayStuff 时,它调用Class a 方法,当virtualClass a 而不是Class b 中时,它调用@987654327 @ 方法。

由于Class c没有实现这个方法,这里应用的规则是什么?

class a
{
public:
void displayStuff() {}
//other methods
};

class b:public a
{
public:
virtual void displayStuff() {}
//other methods
};

class c:public b
{
//other methods
};

【问题讨论】:

  • 您为什么要这样做?它只会让任何想要使用您的类层次结构的人感到困惑。记住,你应该假设一个挥舞斧头的疯子最终会支持它..!
  • 我有一个考试,哦相信我,我们的教授会问我们这样的问题:)

标签: c++ class inheritance virtual-functions


【解决方案1】:

首先,您的案例类 A 没有虚函数。所以它的非虚函数 displayStuff 会被调用。在第二种情况下,当您将函数说明符 virtual 添加到 A 类中的函数时,B 类中的相应函数会重新定义此函数。所以在第二种情况下调用了 B 类的函数,因为虚函数指针表包含一个指向 B 类中定义的函数的指针。

【讨论】:

  • 你的意思是在第一种情况下,我的对象要搜索第一个非虚函数?第二种情况,我的对象会查找“最近的”基类来使用它的方法?
  • 在这两种情况下,编译器都会在 a 类中搜索一个名为 displayStuff 的函数。与第一种情况一样,它不是虚拟的,然后调用它,因为它在 a 类中找到。在第二种情况下,当您添加函数说明符 virtual 时,编译器也会找到该函数。但由于它是虚拟的,编译器会访问写入 b 类函数地址的虚拟函数指针表。所以它调用了b类的函数。
  • 想象每个具有虚函数的对象都包含一个指向虚函数指针表的指针会更简单。由于 c 类没有覆盖 b 类的虚函数,因此表的内容与 b 类相同。
  • 我发现最好自己尝试一下代码,所以我很快实现了它,它符合 Vlad 所说的。drive.google.com/file/d/1mxRQjZgfe9qirOUjCqjSufo5M1ApXzNX/…
  • 样品供将来参考。
【解决方案2】:

由于c类没有实现这个方法,规则是什么 在这里申请?

继承规则适用。根据继承成员的可见性和继承类型,B 类中可见的成员将在 C 类中可见。在这种情况下,由于您是公开继承的,因此所有公共成员都将公开可见。因此,B 类中的公共虚拟成员函数将作为 C 类中的公共虚拟函数可见。

没错,但是当我有多个级别的 继承?

这是一个设计决定。请记住,非虚拟成员函数在编译时绑定,因此在您打算调用该函数之前,无法解析任何通过基指针进行的函数调用。 考虑场景

                                        Base
                                      public: foo
                                       /    \
                                      /      \
                                     /        \
                                    /          \ 
                                   /            \
                                Derived1      Derived2    
                              public: foo   public: foo

Base *p;
std::cin>>cond;
if (cond)
    p = new Derived1();
else
    p = new Derived1();
p->foo();

在上面的代码中,调用 foo()(Derived1::foo 或 Derived2::foo)的决定取决于一些在运行时无法确定的外部条件。使这成为可能的唯一方法是创建一个 vTable,只有在我们使类中的至少一个函数为虚拟时才能强制创建它(请注意,基类中的任何虚拟函数在派生类中继续保持虚拟)。

【讨论】:

  • 没错,但是当我有多个继承级别时,何时使用什么以及为什么?
  • 这有帮助。非常感谢!
猜你喜欢
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-22
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多