0

我正在阅读 Bjarne Stroustrup 的《C++ 编程语言》一书中关于虚拟函数的内容,并遇到了以下代码片段:-

class A {
    //...
    protected:
    int someOtherField;
    //...
    public:
    virtual void print() const;
    //...
};

class B : public A {
    //...
    public:
    void print() const;
    //...
};

void B::print() const {
     A::print();
     cout<<A::someOtherField;
     //...
} 

书中写道

“像在 B::print() 中所做的那样使用范围解析运算符 (::) 调用函数可确保不使用虚拟机制。否则,B::print() 将遭受无限递归。”

我不明白为什么会这样,因为对基类函数的调用正确且明确地告诉我们正在调用 A::print() 而不是其他任何东西。为什么这可能导致无限递归?

编辑 -我放错了关键字“virtual”,对此我感到非常抱歉,但仍在探索这个问题,如果存在以下代码会发生什么?

  • @HTNW 的评论提供了正确的见解
class A {
   //...
   void print() const;
   //...
}

class B : public A {
   //...
   virtual void print() const;
   //...
}
4

2 回答 2

1

如果合格的调用A::print()没有禁用虚拟调度,那么像中所示的用法B::print()将是无限递归,并且几乎不可能从基类调用函数。

如果合格的调用没有禁用虚拟调度,请查看想象中的代码执行:

  1. 你有A* a = new B;
  2. a->print()被调用,虚拟调度确定B::print()应该被调用
  3. B::print()调用的第一条指令A::print(),虚拟调度确定B::print()应该调用
  4. 无限递归

现在,合格调用禁用虚拟调度时的执行序列:

  1. 你有A* a = new B;
  2. a->print()被调用,虚拟调度确定B::print()应该被调用
  3. 调用的第一条指令,就是B::print()调用A::print()了这个函数
  4. A::print()做它的事情并完成
  5. B::print()继续执行。
  6. 没有递归发生。
于 2020-08-24T18:19:58.613 回答
0

否则, B::print() 将遭受无限递归。

这是指没有A:::

void B::print() const {
     print();
     cout<<A::someOtherField;
     //...
}

这只会产生B::print一个递归函数,而不是作者的意图。

于 2020-08-24T18:19:35.447 回答