I tried to "repair" the example in this answer as to demonstrate how a pure virtual function can be called.
#include <iostream>
using namespace std;
class A
{
int id;
public:
A(int i): id(i) {}
int callFoo() { return foo(); }
virtual int foo() = 0;
};
class B: public A
{
public:
B(): A(callFoo()) {}
int foo() { return 3; }
};
int main() {
B b; // <-- this should call a pure virtual function
cout << b.callFoo() << endl;
return 0;
}
But I get no runtime error here (with C++ 4.9.2), but the output 3. I tried the same with Borland C++ 5.6.4, but there I'm getting an access violation. I think that foo()
should be pure virtual in the call of the constructor of the base class.
Who is wrong? Should I try more compilers? Am I right in my understanding of virtual functions?
Your code has Undefined Behaviour: it is UB to call a member function on an object (even a non-virtual one) before all of its base classes have been initialised. C++14 (n4140) 12.6.2/14, emphasis mine:
Member functions (including virtual member functions, 10.3) can be called for an object under construction. Similarly, an object under construction can be the operand of the
typeid
operator (5.2.8) or of adynamic_cast
(5.2.7). However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined. ...
ctor-initializer is the entire list following :
. mem-initializer is one element of this list.