c++classoopclass-hierarchyscope-resolution-operator

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?

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

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

Solution

  • 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.