Consider the following code:
#include <iostream>
using namespace std;
class A
{
public:
virtual void f() = 0;
A(){f();}
};
void A::f() {
cout<<"A"<<endl;
}
class B:public A{
public:
void f(){cout<<"B"<<endl;}
};
int main()
{
B b;
}
In this case I directly call the virtual function from constructor and get compiler warning which says:
warning: abstract virtual 'virtual void A::f()' called from constructor.
But it executes without termination and prints A.
If I wrap the call of the function like this:
class A
{
public:
virtual void f() = 0;
A(){g();}
void g(){f();}
};
void A::f(){cout<<"A"<<endl;}
class B:public A{
public:
void f(){cout<<"B"<<endl;}
};
int main()
{
B b;
}
The compiler does not output any warning during compilation but it crushes at runtime with the following message:
pure virtual method called
terminate called without active exception
Abort
Can anybody explain the behavior of both of this cases?
§ 10.4 Abstract classes [class.abstract] / p6
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.
In brief: The effect of making a call to a pure virtual function directly or indirectly for the object being created from constructor is undefined.
A call to pure virtual member functions cannot be used from a constructor or a destructor, no matter if the call is direct or indirect, because then you end up with an undefined behavior.
The only useful example of providing the implementation of a pure virtual function is when calling it from a derived class:
struct A
{
virtual void f() = 0;
};
void A::f()
{
cout<<"A"<<endl;
}
struct B : A
{
void f()
{
A::f();
cout<<"B"<<endl;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With