Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this not a call of a pure virtual function?

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?

like image 535
Wolf Avatar asked Jun 11 '15 11:06

Wolf


People also ask

Can you call a pure virtual function?

Pure virtual functions must not be called from a C++ constructor. As a general rule, you should never call any kind of virtual function in a constructor or destructor because those calls will never go to a more derived class than the currently executing constructor or destructor.

What happens if you call a pure virtual function?

You may call a virtual function as long as it is not a pure virtual function, and as long as you know that what you are calling is the method from the class itself and not expecting any polymorphism. Calling a pure virtual function from a constructor is undefined behaviour even if it has an implementation.

How do you define a pure virtual function?

A pure virtual function is a virtual function in C++ for which we need not to write any function definition and only we have to declare it. It is declared by assigning 0 in the declaration. An abstract class is a class in C++ which have at least one pure virtual function.


1 Answers

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 a dynamic_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.

like image 92
Angew is no longer proud of SO Avatar answered Nov 10 '22 13:11

Angew is no longer proud of SO