简体   繁体   中英

Why the scope resolution operator (::) does not allow virtual function mechanism? which may lead to infinite recursion otherwise

I was reading about Virtual Functions from the book "The C++ Programming Langauge" by Bjarne Stroustrup, and encountered the following code snippet:-

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;
     //...
} 

It is written in the book that

"Calling a function using the scope resolution operator(::) as done in B::print() ensures that virtual mechanism is not used. Otherwise, B::print() would suffer infinite recursion."

I do not understand why this is the case, since, a call to the base class function correctly and explicitly tells that we are calling A::print() and not anything else. Why this may lead to infinite recursion?

Edit - I misplaced the keyword "virtual", I am extremely sorry for that, but still exploring this question also, What would happen if the following code was there?

  • @HTNW's comment provides proper insights
class A {
   //...
   void print() const;
   //...
}

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

If qualified call A::print() did not disable virtual dispatch, the usage like presented in B::print() would be infinite recursion and it would be pretty much impossible to call function from base class.

See the imaginary code execution if qualified call did not disable virtual dispatch:

  1. You have A* a = new B;
  2. a->print() is called, virtual dispatch determines that B::print() should be called
  3. The first instruction of B::print() calls A::print() , virtual dispatch determines that B::print() should be called
  4. Infinite recursion

Now, an execution sequence when qualified call disables virtual dispatch:

  1. You have A* a = new B;
  2. a->print() is called, virtual dispatch determines that B::print() should be called
  3. The first instruction of B::print() calls A::print() , exactly this function is called
  4. A::print() does its things and finishes
  5. B::print() continues its execution.
  6. No recursion happens.

Otherwise, B::print() would suffer infinite recursion.

This refers to the code without the A:: :

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

This would just make B::print a recursive function, not what the author intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM