1

It's said that in C++ constructor function, as long as the object has not finished construction, shouldn't call virtual function, or else there'll be "pure virtual function call error" thrown out. So I tried this:

#include<stdio.h>
class A{
    virtual void f() = 0;
};

class A1 : public A{
public:
    void f(){printf("virtual function");}
    A1(){f();}
};
int main(int argc, char const *argv[]){
    A1 a;
    return 0;
}

compile it with g++ on windows, it works and prints

virtual function

So how to make my program throw out "pure virtual function call" exception?

Thanks!

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • 1
    Just curious... can you link where this is said? "It's said that in C++ constructor function, as long as the object has not finished construction, shouldn't call virtual function, or else there'll be "pure virtual function call error" thrown out. " – speed_of_light Jun 19 '22 at 07:08
  • As far as I know there's no such exception in the C++ standard. This is a diagnosis crash message of msvc. See https://stackoverflow.com/questions/99552/where-do-pure-virtual-function-call-crashes-come-from, it describes when such messages can occur. I would vote to close the question as a duplicate of this link. – 273K Jun 19 '22 at 07:08
  • 1
    The road to hell is paved with virtual functions calls in constructors – AlexStepanov Jun 19 '22 at 07:12
  • You've probably gotten the rule wrong. The constructor will call the most inherited virtual up to the level of the class being constructed, but won't go any deeper. See here: https://stackoverflow.com/a/45832805/4885321 – alagner Jun 19 '22 at 07:12
  • Calling a virtual function in a constructor does not result in any exception. The behaviour you are seeing (calling `A1::f()` since that is the most derived version of `f()` for class `A1`) is correct. – Peter Jun 19 '22 at 07:16

1 Answers1

7

You are not getting the "pure virtual method call" exception because A::f() is not being called.

A1's constructor is calling its own A1::f() method, which is perfectly safe to do during A1's construction.

The issue with calling a virtual method in a constructor has to do with a base class constructor calling a derived class method, which doesn't work since the derived portion of the object being constructed doesn't exist yet.

So, to get the exception you want, you need to call f() in A's constructor rather than in A1's constructor.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770