Constructor calling virtual child function c++ [duplicate] - c++

Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
class B : public A
{
public:
B() : A() {}
virtual void fn() { _n = 2; }
};
If I write the following code:
int main()
{
B b;
int n = b.getn();
}
One might expect that n is set to 2.
It turns out that n is set to 1. Why?

Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
[...]
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
EDIT Corrected Most to All (thanks litb)

Calling a polymorphic function from a constructor is a recipe for disaster in most OO languages. Different languages will perform differently when this situation is encountered.
The basic problem is that in all languages the Base type(s) must be constructed previous to the Derived type. Now, the problem is what does it mean to call a polymorphic method from the constructor. What do you expect it to behave like? There are two approaches: call the method at the Base level (C++ style) or call the polymorphic method on an unconstructed object at the bottom of the hierarchy (Java way).
In C++ the Base class will build its version of the virtual method table prior to entering its own construction. At this point a call to the virtual method will end up calling the Base version of the method or producing a pure virtual method called in case it has no implementation at that level of the hierarchy. After the Base has been fully constructed, the compiler will start building the Derived class, and it will override the method pointers to point to the implementations in the next level of the hierarchy.
class Base {
public:
Base() { f(); }
virtual void f() { std::cout << "Base" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() {}
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d;
}
// outputs: "Base" as the vtable still points to Base::f() when Base::Base() is run
In Java, the compiler will build the virtual table equivalent at the very first step of construction, prior to entering the Base constructor or Derived constructor. The implications are different (and to my likings more dangerous). If the base class constructor calls a method that is overriden in the derived class the call will actually be handled at the derived level calling a method on an unconstructed object, yielding unexpected results. All attributes of the derived class that are initialized inside the constructor block are yet uninitialized, including 'final' attributes. Elements that have a default value defined at the class level will have that value.
public class Base {
public Base() { polymorphic(); }
public void polymorphic() {
System.out.println( "Base" );
}
}
public class Derived extends Base
{
final int x;
public Derived( int value ) {
x = value;
polymorphic();
}
public void polymorphic() {
System.out.println( "Derived: " + x );
}
public static void main( String args[] ) {
Derived d = new Derived( 5 );
}
}
// outputs: Derived 0
// Derived 5
// ... so much for final attributes never changing :P
As you see, calling a polymorphic (virtual in C++ terminology) methods is a common source of errors. In C++, at least you have the guarantee that it will never call a method on a yet unconstructed object...

The reason is that C++ objects are constructed like onions, from the inside out. Base classes are constructed before derived classes. So, before a B can be made, an A must be made. When A's constructor is called, it's not a B yet, so the virtual function table still has the entry for A's copy of fn().

The C++ FAQ Lite Covers this pretty well:
Essentially, during the call to the base classes constructor, the object is not yet of the derived type and thus the base type's implementation of the virtual function is called and not the derived type's.

One solution to your problem is using factory methods to create your object.
Define a common base class for your class hierarchy containing a virtual method afterConstruction():
class Object
{
public:
virtual void afterConstruction() {}
// ...
};
Define a factory method:
template< class C >
C* factoryNew()
{
C* pObject = new C();
pObject->afterConstruction();
return pObject;
}
Use it like this:
class MyClass : public Object
{
public:
virtual void afterConstruction()
{
// do something.
}
// ...
};
MyClass* pMyObject = factoryNew();

The C++ Standard (ISO/IEC 14882-2014) say's:
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.
So, attempting to call a derived class function from a base class under construction is dangerous.Similarly, an object is destroyed in reverse order from construction, so attempting to call a function in a more derived class from a destructor may access resources that have already been released.

As has been pointed out, the objects are created base-down upon construction. When the base object is being constructed, the derived object does not exist yet, so a virtual function override cannot work.
However, this can be solved with polymorphic getters that use static polymorphism instead of virtual functions if your getters return constants, or otherwise can be expressed in a static member function, This example uses CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
template<typename DerivedClass>
class Base
{
public:
inline Base() :
foo(DerivedClass::getFoo())
{}
inline int fooSq() {
return foo * foo;
}
const int foo;
};
class A : public Base<A>
{
public:
inline static int getFoo() { return 1; }
};
class B : public Base<B>
{
public:
inline static int getFoo() { return 2; }
};
class C : public Base<C>
{
public:
inline static int getFoo() { return 3; }
};
int main()
{
A a;
B b;
C c;
std::cout << a.fooSq() << ", " << b.fooSq() << ", " << c.fooSq() << std::endl;
return 0;
}
With the use of static polymorphism, the base class knows which class' getter to call as the information is provided at compile-time.

Do you know the crash error from Windows explorer?! "Pure virtual function call ..."
Same problem ...
class AbstractClass
{
public:
AbstractClass( ){
//if you call pureVitualFunction I will crash...
}
virtual void pureVitualFunction() = 0;
};
Because there is no implemetation for the function pureVitualFunction() and the function is called in the constructor the program will crash.

The vtables are created by the compiler.
A class object has a pointer to its vtable. When it starts life, that vtable pointer points to the vtable
of the base class. At the end of the constructor code, the compiler generates code to re-point the vtable pointer
to the actual vtable for the class. This ensures that constructor code that calls virtual functions calls the
base class implementations of those functions, not the override in the class.

Firstly,Object is created and then we assign it 's address to pointers.Constructors are called at the time of object creation and used to initializ the value of data members. Pointer to object comes into scenario after object creation. Thats why, C++ do not allows us to make constructors as virtual .
.another reason is that, There is nothing like pointer to constructor , which can point to virtual constructor,because one of the property of virtual function is that it can be used by pointers only.
Virtual functions are used to assign value dynamically,as constructors are static,so we can not make them virtual.

As a supplement, calling a virtual function of an object that has not yet completed construction will face the same problem.
For example, start a new thread in the constructor of an object, and pass the object to the new thread, if the new thread calling the virtual function of that object before the object completed construction will cause unexpected result.
For example:
#include <thread>
#include <string>
#include <iostream>
#include <chrono>
class Base
{
public:
Base()
{
std::thread worker([this] {
// This will print "Base" rather than "Sub".
this->Print();
});
worker.detach();
// Try comment out this code to see different output.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
class Sub : public Base
{
public:
void Print() override
{
std::cout << "Sub" << std::endl;
}
};
int main()
{
Sub sub;
sub.Print();
getchar();
return 0;
}
This will output:
Base
Sub

To answer what happens/why when you run that code, I compiled it via
g++ -ggdb main.cc, and stepped through with gdb.
main.cc:
class A {
public:
A() {
fn();
}
virtual void fn() { _n=1; }
int getn() { return _n; }
protected:
int _n;
};
class B: public A {
public:
B() {
// fn();
}
void fn() override {
_n = 2;
}
};
int main() {
B b;
}
Setting a break point at main, then stepping into B(), printing the this ptr, taking a step into A() (base constructor):
(gdb) step
B::B (this=0x7fffffffde80) at main2.cc:16
16 B() {
(gdb) p this
$27 = (B * const) 0x7fffffffde80
(gdb) p *this
$28 = {<A> = {_vptr.A = 0x7fffffffdf80, _n = 0}, <No data fields>}
(gdb) s
A::A (this=0x7fffffffde80) at main2.cc:3
3 A() {
(gdb) p this
$29 = (A * const) 0x7fffffffde80
shows that this initially points at the derived B obj b being constructed on the stack at 0x7fffffffde80. The next step is into the base A() ctor and this becomes A * const to the same address, which makes sense as the base A is right in the start of B object. but it still hasn't been constructed:
(gdb) p *this
$30 = {_vptr.A = 0x7fffffffdf80, _n = 0}
One more step:
(gdb) s
4 fn();
(gdb) p *this
$31 = {_vptr.A = 0x402038 <vtable for A+16>, _n = 0}
_n has been initialized, and it's virtual function table pointer contains the address of virtual void A::fn():
(gdb) p fn
$32 = {void (A * const)} 0x40114a <A::fn()>
(gdb) x/1a 0x402038
0x402038 <_ZTV1A+16>: 0x40114a <_ZN1A2fnEv>
So it makes perfect sense that the next step executes A::fn() via this->fn() given the active this and _vptr.A. Another step and we're back in B() ctor:
(gdb) s
B::B (this=0x7fffffffde80) at main2.cc:18
18 }
(gdb) p this
$34 = (B * const) 0x7fffffffde80
(gdb) p *this
$35 = {<A> = {_vptr.A = 0x402020 <vtable for B+16>, _n = 1}, <No data fields>}
The base A has been constructed. Note that address stored in the virtual function table pointer has changed to the vtable for derived class B. And so a call to fn() would select the derived class override B::fn() via this->fn() given the active this and _vptr.A (un-comment call to B::fn() in B() to see this.) Again examining 1 address stored in _vptr.A shows it now points to the derived class override:
(gdb) p fn
$36 = {void (B * const)} 0x401188 <B::fn()>
(gdb) x/1a 0x402020
0x402020 <_ZTV1B+16>: 0x401188 <_ZN1B2fnEv>
By looking at this example, and by looking at one with a 3 level inheritance, it appears that as the compiler descends to construct the base sub-objects, the type of this* and the corresponding address in _vptr.A change to reflect the current sub-object being constructed, - so it gets left pointing to the most derived type's. So we would expect virtual functions called from within ctors to choose the function for that level, i.e., same result as if they were non-virtual.. Likewise for dtors but in reverse. And this becomes a ptr to member while members are being constructed so they also properly call any virtual functions that are defined for them.

I just had this error in a program.
And I had this thinking : what happens if the method is marked as pure virtual in the constructor?
class Base {
public:
virtual int getInt() = 0;
Base(){
printf("int=%d\n", getInt());
}
};
class Derived : public Base {
public:
virtual int getInt() override {return 1;}
};
And... funny thing! You first get a warining by the compiler :
warning: pure virtual ‘virtual int Base::getInt() const’ called from constructor
And an error from ld!
/usr/bin/ld: /tmp/ccsaJnuH.o: in function `Base::Base()':
main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0x26): undefined reference to `Base::getInt()'
collect2: error: ld returned 1 exit status
This is totally illogic that you get just a warning from the compiler!

I am not seeing the importance of the virtual key word here. b is a static-typed variable, and its type is determined by compiler at compile time. The function calls would not reference the vtable. When b is constructed, its parent class's constructor is called, which is why the value of _n is set to 1.

During the object's constructor call the virtual function pointer table is not completely built. Doing this will usually not give you the behavior you expect. Calling a virtual function in this situation may work but is not guaranteed and should be avoided to be portable and follow the C++ standard.

Related

C++ How to call subclass method from method in superclass? [duplicate]

Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
class B : public A
{
public:
B() : A() {}
virtual void fn() { _n = 2; }
};
If I write the following code:
int main()
{
B b;
int n = b.getn();
}
One might expect that n is set to 2.
It turns out that n is set to 1. Why?
Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
[...]
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
EDIT Corrected Most to All (thanks litb)
Calling a polymorphic function from a constructor is a recipe for disaster in most OO languages. Different languages will perform differently when this situation is encountered.
The basic problem is that in all languages the Base type(s) must be constructed previous to the Derived type. Now, the problem is what does it mean to call a polymorphic method from the constructor. What do you expect it to behave like? There are two approaches: call the method at the Base level (C++ style) or call the polymorphic method on an unconstructed object at the bottom of the hierarchy (Java way).
In C++ the Base class will build its version of the virtual method table prior to entering its own construction. At this point a call to the virtual method will end up calling the Base version of the method or producing a pure virtual method called in case it has no implementation at that level of the hierarchy. After the Base has been fully constructed, the compiler will start building the Derived class, and it will override the method pointers to point to the implementations in the next level of the hierarchy.
class Base {
public:
Base() { f(); }
virtual void f() { std::cout << "Base" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() {}
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d;
}
// outputs: "Base" as the vtable still points to Base::f() when Base::Base() is run
In Java, the compiler will build the virtual table equivalent at the very first step of construction, prior to entering the Base constructor or Derived constructor. The implications are different (and to my likings more dangerous). If the base class constructor calls a method that is overriden in the derived class the call will actually be handled at the derived level calling a method on an unconstructed object, yielding unexpected results. All attributes of the derived class that are initialized inside the constructor block are yet uninitialized, including 'final' attributes. Elements that have a default value defined at the class level will have that value.
public class Base {
public Base() { polymorphic(); }
public void polymorphic() {
System.out.println( "Base" );
}
}
public class Derived extends Base
{
final int x;
public Derived( int value ) {
x = value;
polymorphic();
}
public void polymorphic() {
System.out.println( "Derived: " + x );
}
public static void main( String args[] ) {
Derived d = new Derived( 5 );
}
}
// outputs: Derived 0
// Derived 5
// ... so much for final attributes never changing :P
As you see, calling a polymorphic (virtual in C++ terminology) methods is a common source of errors. In C++, at least you have the guarantee that it will never call a method on a yet unconstructed object...
The reason is that C++ objects are constructed like onions, from the inside out. Base classes are constructed before derived classes. So, before a B can be made, an A must be made. When A's constructor is called, it's not a B yet, so the virtual function table still has the entry for A's copy of fn().
The C++ FAQ Lite Covers this pretty well:
Essentially, during the call to the base classes constructor, the object is not yet of the derived type and thus the base type's implementation of the virtual function is called and not the derived type's.
One solution to your problem is using factory methods to create your object.
Define a common base class for your class hierarchy containing a virtual method afterConstruction():
class Object
{
public:
virtual void afterConstruction() {}
// ...
};
Define a factory method:
template< class C >
C* factoryNew()
{
C* pObject = new C();
pObject->afterConstruction();
return pObject;
}
Use it like this:
class MyClass : public Object
{
public:
virtual void afterConstruction()
{
// do something.
}
// ...
};
MyClass* pMyObject = factoryNew();
The C++ Standard (ISO/IEC 14882-2014) say's:
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.
So, attempting to call a derived class function from a base class under construction is dangerous.Similarly, an object is destroyed in reverse order from construction, so attempting to call a function in a more derived class from a destructor may access resources that have already been released.
As has been pointed out, the objects are created base-down upon construction. When the base object is being constructed, the derived object does not exist yet, so a virtual function override cannot work.
However, this can be solved with polymorphic getters that use static polymorphism instead of virtual functions if your getters return constants, or otherwise can be expressed in a static member function, This example uses CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
template<typename DerivedClass>
class Base
{
public:
inline Base() :
foo(DerivedClass::getFoo())
{}
inline int fooSq() {
return foo * foo;
}
const int foo;
};
class A : public Base<A>
{
public:
inline static int getFoo() { return 1; }
};
class B : public Base<B>
{
public:
inline static int getFoo() { return 2; }
};
class C : public Base<C>
{
public:
inline static int getFoo() { return 3; }
};
int main()
{
A a;
B b;
C c;
std::cout << a.fooSq() << ", " << b.fooSq() << ", " << c.fooSq() << std::endl;
return 0;
}
With the use of static polymorphism, the base class knows which class' getter to call as the information is provided at compile-time.
Do you know the crash error from Windows explorer?! "Pure virtual function call ..."
Same problem ...
class AbstractClass
{
public:
AbstractClass( ){
//if you call pureVitualFunction I will crash...
}
virtual void pureVitualFunction() = 0;
};
Because there is no implemetation for the function pureVitualFunction() and the function is called in the constructor the program will crash.
The vtables are created by the compiler.
A class object has a pointer to its vtable. When it starts life, that vtable pointer points to the vtable
of the base class. At the end of the constructor code, the compiler generates code to re-point the vtable pointer
to the actual vtable for the class. This ensures that constructor code that calls virtual functions calls the
base class implementations of those functions, not the override in the class.
Firstly,Object is created and then we assign it 's address to pointers.Constructors are called at the time of object creation and used to initializ the value of data members. Pointer to object comes into scenario after object creation. Thats why, C++ do not allows us to make constructors as virtual .
.another reason is that, There is nothing like pointer to constructor , which can point to virtual constructor,because one of the property of virtual function is that it can be used by pointers only.
Virtual functions are used to assign value dynamically,as constructors are static,so we can not make them virtual.
As a supplement, calling a virtual function of an object that has not yet completed construction will face the same problem.
For example, start a new thread in the constructor of an object, and pass the object to the new thread, if the new thread calling the virtual function of that object before the object completed construction will cause unexpected result.
For example:
#include <thread>
#include <string>
#include <iostream>
#include <chrono>
class Base
{
public:
Base()
{
std::thread worker([this] {
// This will print "Base" rather than "Sub".
this->Print();
});
worker.detach();
// Try comment out this code to see different output.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
class Sub : public Base
{
public:
void Print() override
{
std::cout << "Sub" << std::endl;
}
};
int main()
{
Sub sub;
sub.Print();
getchar();
return 0;
}
This will output:
Base
Sub
To answer what happens/why when you run that code, I compiled it via
g++ -ggdb main.cc, and stepped through with gdb.
main.cc:
class A {
public:
A() {
fn();
}
virtual void fn() { _n=1; }
int getn() { return _n; }
protected:
int _n;
};
class B: public A {
public:
B() {
// fn();
}
void fn() override {
_n = 2;
}
};
int main() {
B b;
}
Setting a break point at main, then stepping into B(), printing the this ptr, taking a step into A() (base constructor):
(gdb) step
B::B (this=0x7fffffffde80) at main2.cc:16
16 B() {
(gdb) p this
$27 = (B * const) 0x7fffffffde80
(gdb) p *this
$28 = {<A> = {_vptr.A = 0x7fffffffdf80, _n = 0}, <No data fields>}
(gdb) s
A::A (this=0x7fffffffde80) at main2.cc:3
3 A() {
(gdb) p this
$29 = (A * const) 0x7fffffffde80
shows that this initially points at the derived B obj b being constructed on the stack at 0x7fffffffde80. The next step is into the base A() ctor and this becomes A * const to the same address, which makes sense as the base A is right in the start of B object. but it still hasn't been constructed:
(gdb) p *this
$30 = {_vptr.A = 0x7fffffffdf80, _n = 0}
One more step:
(gdb) s
4 fn();
(gdb) p *this
$31 = {_vptr.A = 0x402038 <vtable for A+16>, _n = 0}
_n has been initialized, and it's virtual function table pointer contains the address of virtual void A::fn():
(gdb) p fn
$32 = {void (A * const)} 0x40114a <A::fn()>
(gdb) x/1a 0x402038
0x402038 <_ZTV1A+16>: 0x40114a <_ZN1A2fnEv>
So it makes perfect sense that the next step executes A::fn() via this->fn() given the active this and _vptr.A. Another step and we're back in B() ctor:
(gdb) s
B::B (this=0x7fffffffde80) at main2.cc:18
18 }
(gdb) p this
$34 = (B * const) 0x7fffffffde80
(gdb) p *this
$35 = {<A> = {_vptr.A = 0x402020 <vtable for B+16>, _n = 1}, <No data fields>}
The base A has been constructed. Note that address stored in the virtual function table pointer has changed to the vtable for derived class B. And so a call to fn() would select the derived class override B::fn() via this->fn() given the active this and _vptr.A (un-comment call to B::fn() in B() to see this.) Again examining 1 address stored in _vptr.A shows it now points to the derived class override:
(gdb) p fn
$36 = {void (B * const)} 0x401188 <B::fn()>
(gdb) x/1a 0x402020
0x402020 <_ZTV1B+16>: 0x401188 <_ZN1B2fnEv>
By looking at this example, and by looking at one with a 3 level inheritance, it appears that as the compiler descends to construct the base sub-objects, the type of this* and the corresponding address in _vptr.A change to reflect the current sub-object being constructed, - so it gets left pointing to the most derived type's. So we would expect virtual functions called from within ctors to choose the function for that level, i.e., same result as if they were non-virtual.. Likewise for dtors but in reverse. And this becomes a ptr to member while members are being constructed so they also properly call any virtual functions that are defined for them.
I just had this error in a program.
And I had this thinking : what happens if the method is marked as pure virtual in the constructor?
class Base {
public:
virtual int getInt() = 0;
Base(){
printf("int=%d\n", getInt());
}
};
class Derived : public Base {
public:
virtual int getInt() override {return 1;}
};
And... funny thing! You first get a warining by the compiler :
warning: pure virtual ‘virtual int Base::getInt() const’ called from constructor
And an error from ld!
/usr/bin/ld: /tmp/ccsaJnuH.o: in function `Base::Base()':
main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0x26): undefined reference to `Base::getInt()'
collect2: error: ld returned 1 exit status
This is totally illogic that you get just a warning from the compiler!
I am not seeing the importance of the virtual key word here. b is a static-typed variable, and its type is determined by compiler at compile time. The function calls would not reference the vtable. When b is constructed, its parent class's constructor is called, which is why the value of _n is set to 1.
During the object's constructor call the virtual function pointer table is not completely built. Doing this will usually not give you the behavior you expect. Calling a virtual function in this situation may work but is not guaranteed and should be avoided to be portable and follow the C++ standard.

Confusion about using override with constructors [duplicate]

Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
class B : public A
{
public:
B() : A() {}
virtual void fn() { _n = 2; }
};
If I write the following code:
int main()
{
B b;
int n = b.getn();
}
One might expect that n is set to 2.
It turns out that n is set to 1. Why?
Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
[...]
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
EDIT Corrected Most to All (thanks litb)
Calling a polymorphic function from a constructor is a recipe for disaster in most OO languages. Different languages will perform differently when this situation is encountered.
The basic problem is that in all languages the Base type(s) must be constructed previous to the Derived type. Now, the problem is what does it mean to call a polymorphic method from the constructor. What do you expect it to behave like? There are two approaches: call the method at the Base level (C++ style) or call the polymorphic method on an unconstructed object at the bottom of the hierarchy (Java way).
In C++ the Base class will build its version of the virtual method table prior to entering its own construction. At this point a call to the virtual method will end up calling the Base version of the method or producing a pure virtual method called in case it has no implementation at that level of the hierarchy. After the Base has been fully constructed, the compiler will start building the Derived class, and it will override the method pointers to point to the implementations in the next level of the hierarchy.
class Base {
public:
Base() { f(); }
virtual void f() { std::cout << "Base" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() {}
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d;
}
// outputs: "Base" as the vtable still points to Base::f() when Base::Base() is run
In Java, the compiler will build the virtual table equivalent at the very first step of construction, prior to entering the Base constructor or Derived constructor. The implications are different (and to my likings more dangerous). If the base class constructor calls a method that is overriden in the derived class the call will actually be handled at the derived level calling a method on an unconstructed object, yielding unexpected results. All attributes of the derived class that are initialized inside the constructor block are yet uninitialized, including 'final' attributes. Elements that have a default value defined at the class level will have that value.
public class Base {
public Base() { polymorphic(); }
public void polymorphic() {
System.out.println( "Base" );
}
}
public class Derived extends Base
{
final int x;
public Derived( int value ) {
x = value;
polymorphic();
}
public void polymorphic() {
System.out.println( "Derived: " + x );
}
public static void main( String args[] ) {
Derived d = new Derived( 5 );
}
}
// outputs: Derived 0
// Derived 5
// ... so much for final attributes never changing :P
As you see, calling a polymorphic (virtual in C++ terminology) methods is a common source of errors. In C++, at least you have the guarantee that it will never call a method on a yet unconstructed object...
The reason is that C++ objects are constructed like onions, from the inside out. Base classes are constructed before derived classes. So, before a B can be made, an A must be made. When A's constructor is called, it's not a B yet, so the virtual function table still has the entry for A's copy of fn().
The C++ FAQ Lite Covers this pretty well:
Essentially, during the call to the base classes constructor, the object is not yet of the derived type and thus the base type's implementation of the virtual function is called and not the derived type's.
One solution to your problem is using factory methods to create your object.
Define a common base class for your class hierarchy containing a virtual method afterConstruction():
class Object
{
public:
virtual void afterConstruction() {}
// ...
};
Define a factory method:
template< class C >
C* factoryNew()
{
C* pObject = new C();
pObject->afterConstruction();
return pObject;
}
Use it like this:
class MyClass : public Object
{
public:
virtual void afterConstruction()
{
// do something.
}
// ...
};
MyClass* pMyObject = factoryNew();
The C++ Standard (ISO/IEC 14882-2014) say's:
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.
So, attempting to call a derived class function from a base class under construction is dangerous.Similarly, an object is destroyed in reverse order from construction, so attempting to call a function in a more derived class from a destructor may access resources that have already been released.
As has been pointed out, the objects are created base-down upon construction. When the base object is being constructed, the derived object does not exist yet, so a virtual function override cannot work.
However, this can be solved with polymorphic getters that use static polymorphism instead of virtual functions if your getters return constants, or otherwise can be expressed in a static member function, This example uses CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
template<typename DerivedClass>
class Base
{
public:
inline Base() :
foo(DerivedClass::getFoo())
{}
inline int fooSq() {
return foo * foo;
}
const int foo;
};
class A : public Base<A>
{
public:
inline static int getFoo() { return 1; }
};
class B : public Base<B>
{
public:
inline static int getFoo() { return 2; }
};
class C : public Base<C>
{
public:
inline static int getFoo() { return 3; }
};
int main()
{
A a;
B b;
C c;
std::cout << a.fooSq() << ", " << b.fooSq() << ", " << c.fooSq() << std::endl;
return 0;
}
With the use of static polymorphism, the base class knows which class' getter to call as the information is provided at compile-time.
Do you know the crash error from Windows explorer?! "Pure virtual function call ..."
Same problem ...
class AbstractClass
{
public:
AbstractClass( ){
//if you call pureVitualFunction I will crash...
}
virtual void pureVitualFunction() = 0;
};
Because there is no implemetation for the function pureVitualFunction() and the function is called in the constructor the program will crash.
The vtables are created by the compiler.
A class object has a pointer to its vtable. When it starts life, that vtable pointer points to the vtable
of the base class. At the end of the constructor code, the compiler generates code to re-point the vtable pointer
to the actual vtable for the class. This ensures that constructor code that calls virtual functions calls the
base class implementations of those functions, not the override in the class.
Firstly,Object is created and then we assign it 's address to pointers.Constructors are called at the time of object creation and used to initializ the value of data members. Pointer to object comes into scenario after object creation. Thats why, C++ do not allows us to make constructors as virtual .
.another reason is that, There is nothing like pointer to constructor , which can point to virtual constructor,because one of the property of virtual function is that it can be used by pointers only.
Virtual functions are used to assign value dynamically,as constructors are static,so we can not make them virtual.
As a supplement, calling a virtual function of an object that has not yet completed construction will face the same problem.
For example, start a new thread in the constructor of an object, and pass the object to the new thread, if the new thread calling the virtual function of that object before the object completed construction will cause unexpected result.
For example:
#include <thread>
#include <string>
#include <iostream>
#include <chrono>
class Base
{
public:
Base()
{
std::thread worker([this] {
// This will print "Base" rather than "Sub".
this->Print();
});
worker.detach();
// Try comment out this code to see different output.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
class Sub : public Base
{
public:
void Print() override
{
std::cout << "Sub" << std::endl;
}
};
int main()
{
Sub sub;
sub.Print();
getchar();
return 0;
}
This will output:
Base
Sub
To answer what happens/why when you run that code, I compiled it via
g++ -ggdb main.cc, and stepped through with gdb.
main.cc:
class A {
public:
A() {
fn();
}
virtual void fn() { _n=1; }
int getn() { return _n; }
protected:
int _n;
};
class B: public A {
public:
B() {
// fn();
}
void fn() override {
_n = 2;
}
};
int main() {
B b;
}
Setting a break point at main, then stepping into B(), printing the this ptr, taking a step into A() (base constructor):
(gdb) step
B::B (this=0x7fffffffde80) at main2.cc:16
16 B() {
(gdb) p this
$27 = (B * const) 0x7fffffffde80
(gdb) p *this
$28 = {<A> = {_vptr.A = 0x7fffffffdf80, _n = 0}, <No data fields>}
(gdb) s
A::A (this=0x7fffffffde80) at main2.cc:3
3 A() {
(gdb) p this
$29 = (A * const) 0x7fffffffde80
shows that this initially points at the derived B obj b being constructed on the stack at 0x7fffffffde80. The next step is into the base A() ctor and this becomes A * const to the same address, which makes sense as the base A is right in the start of B object. but it still hasn't been constructed:
(gdb) p *this
$30 = {_vptr.A = 0x7fffffffdf80, _n = 0}
One more step:
(gdb) s
4 fn();
(gdb) p *this
$31 = {_vptr.A = 0x402038 <vtable for A+16>, _n = 0}
_n has been initialized, and it's virtual function table pointer contains the address of virtual void A::fn():
(gdb) p fn
$32 = {void (A * const)} 0x40114a <A::fn()>
(gdb) x/1a 0x402038
0x402038 <_ZTV1A+16>: 0x40114a <_ZN1A2fnEv>
So it makes perfect sense that the next step executes A::fn() via this->fn() given the active this and _vptr.A. Another step and we're back in B() ctor:
(gdb) s
B::B (this=0x7fffffffde80) at main2.cc:18
18 }
(gdb) p this
$34 = (B * const) 0x7fffffffde80
(gdb) p *this
$35 = {<A> = {_vptr.A = 0x402020 <vtable for B+16>, _n = 1}, <No data fields>}
The base A has been constructed. Note that address stored in the virtual function table pointer has changed to the vtable for derived class B. And so a call to fn() would select the derived class override B::fn() via this->fn() given the active this and _vptr.A (un-comment call to B::fn() in B() to see this.) Again examining 1 address stored in _vptr.A shows it now points to the derived class override:
(gdb) p fn
$36 = {void (B * const)} 0x401188 <B::fn()>
(gdb) x/1a 0x402020
0x402020 <_ZTV1B+16>: 0x401188 <_ZN1B2fnEv>
By looking at this example, and by looking at one with a 3 level inheritance, it appears that as the compiler descends to construct the base sub-objects, the type of this* and the corresponding address in _vptr.A change to reflect the current sub-object being constructed, - so it gets left pointing to the most derived type's. So we would expect virtual functions called from within ctors to choose the function for that level, i.e., same result as if they were non-virtual.. Likewise for dtors but in reverse. And this becomes a ptr to member while members are being constructed so they also properly call any virtual functions that are defined for them.
I just had this error in a program.
And I had this thinking : what happens if the method is marked as pure virtual in the constructor?
class Base {
public:
virtual int getInt() = 0;
Base(){
printf("int=%d\n", getInt());
}
};
class Derived : public Base {
public:
virtual int getInt() override {return 1;}
};
And... funny thing! You first get a warining by the compiler :
warning: pure virtual ‘virtual int Base::getInt() const’ called from constructor
And an error from ld!
/usr/bin/ld: /tmp/ccsaJnuH.o: in function `Base::Base()':
main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0x26): undefined reference to `Base::getInt()'
collect2: error: ld returned 1 exit status
This is totally illogic that you get just a warning from the compiler!
I am not seeing the importance of the virtual key word here. b is a static-typed variable, and its type is determined by compiler at compile time. The function calls would not reference the vtable. When b is constructed, its parent class's constructor is called, which is why the value of _n is set to 1.
During the object's constructor call the virtual function pointer table is not completely built. Doing this will usually not give you the behavior you expect. Calling a virtual function in this situation may work but is not guaranteed and should be avoided to be portable and follow the C++ standard.

C++ Subclass method overriding [duplicate]

Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
class B : public A
{
public:
B() : A() {}
virtual void fn() { _n = 2; }
};
If I write the following code:
int main()
{
B b;
int n = b.getn();
}
One might expect that n is set to 2.
It turns out that n is set to 1. Why?
Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
[...]
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
EDIT Corrected Most to All (thanks litb)
Calling a polymorphic function from a constructor is a recipe for disaster in most OO languages. Different languages will perform differently when this situation is encountered.
The basic problem is that in all languages the Base type(s) must be constructed previous to the Derived type. Now, the problem is what does it mean to call a polymorphic method from the constructor. What do you expect it to behave like? There are two approaches: call the method at the Base level (C++ style) or call the polymorphic method on an unconstructed object at the bottom of the hierarchy (Java way).
In C++ the Base class will build its version of the virtual method table prior to entering its own construction. At this point a call to the virtual method will end up calling the Base version of the method or producing a pure virtual method called in case it has no implementation at that level of the hierarchy. After the Base has been fully constructed, the compiler will start building the Derived class, and it will override the method pointers to point to the implementations in the next level of the hierarchy.
class Base {
public:
Base() { f(); }
virtual void f() { std::cout << "Base" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() {}
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d;
}
// outputs: "Base" as the vtable still points to Base::f() when Base::Base() is run
In Java, the compiler will build the virtual table equivalent at the very first step of construction, prior to entering the Base constructor or Derived constructor. The implications are different (and to my likings more dangerous). If the base class constructor calls a method that is overriden in the derived class the call will actually be handled at the derived level calling a method on an unconstructed object, yielding unexpected results. All attributes of the derived class that are initialized inside the constructor block are yet uninitialized, including 'final' attributes. Elements that have a default value defined at the class level will have that value.
public class Base {
public Base() { polymorphic(); }
public void polymorphic() {
System.out.println( "Base" );
}
}
public class Derived extends Base
{
final int x;
public Derived( int value ) {
x = value;
polymorphic();
}
public void polymorphic() {
System.out.println( "Derived: " + x );
}
public static void main( String args[] ) {
Derived d = new Derived( 5 );
}
}
// outputs: Derived 0
// Derived 5
// ... so much for final attributes never changing :P
As you see, calling a polymorphic (virtual in C++ terminology) methods is a common source of errors. In C++, at least you have the guarantee that it will never call a method on a yet unconstructed object...
The reason is that C++ objects are constructed like onions, from the inside out. Base classes are constructed before derived classes. So, before a B can be made, an A must be made. When A's constructor is called, it's not a B yet, so the virtual function table still has the entry for A's copy of fn().
The C++ FAQ Lite Covers this pretty well:
Essentially, during the call to the base classes constructor, the object is not yet of the derived type and thus the base type's implementation of the virtual function is called and not the derived type's.
One solution to your problem is using factory methods to create your object.
Define a common base class for your class hierarchy containing a virtual method afterConstruction():
class Object
{
public:
virtual void afterConstruction() {}
// ...
};
Define a factory method:
template< class C >
C* factoryNew()
{
C* pObject = new C();
pObject->afterConstruction();
return pObject;
}
Use it like this:
class MyClass : public Object
{
public:
virtual void afterConstruction()
{
// do something.
}
// ...
};
MyClass* pMyObject = factoryNew();
The C++ Standard (ISO/IEC 14882-2014) say's:
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.
So, attempting to call a derived class function from a base class under construction is dangerous.Similarly, an object is destroyed in reverse order from construction, so attempting to call a function in a more derived class from a destructor may access resources that have already been released.
As has been pointed out, the objects are created base-down upon construction. When the base object is being constructed, the derived object does not exist yet, so a virtual function override cannot work.
However, this can be solved with polymorphic getters that use static polymorphism instead of virtual functions if your getters return constants, or otherwise can be expressed in a static member function, This example uses CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
template<typename DerivedClass>
class Base
{
public:
inline Base() :
foo(DerivedClass::getFoo())
{}
inline int fooSq() {
return foo * foo;
}
const int foo;
};
class A : public Base<A>
{
public:
inline static int getFoo() { return 1; }
};
class B : public Base<B>
{
public:
inline static int getFoo() { return 2; }
};
class C : public Base<C>
{
public:
inline static int getFoo() { return 3; }
};
int main()
{
A a;
B b;
C c;
std::cout << a.fooSq() << ", " << b.fooSq() << ", " << c.fooSq() << std::endl;
return 0;
}
With the use of static polymorphism, the base class knows which class' getter to call as the information is provided at compile-time.
Do you know the crash error from Windows explorer?! "Pure virtual function call ..."
Same problem ...
class AbstractClass
{
public:
AbstractClass( ){
//if you call pureVitualFunction I will crash...
}
virtual void pureVitualFunction() = 0;
};
Because there is no implemetation for the function pureVitualFunction() and the function is called in the constructor the program will crash.
The vtables are created by the compiler.
A class object has a pointer to its vtable. When it starts life, that vtable pointer points to the vtable
of the base class. At the end of the constructor code, the compiler generates code to re-point the vtable pointer
to the actual vtable for the class. This ensures that constructor code that calls virtual functions calls the
base class implementations of those functions, not the override in the class.
Firstly,Object is created and then we assign it 's address to pointers.Constructors are called at the time of object creation and used to initializ the value of data members. Pointer to object comes into scenario after object creation. Thats why, C++ do not allows us to make constructors as virtual .
.another reason is that, There is nothing like pointer to constructor , which can point to virtual constructor,because one of the property of virtual function is that it can be used by pointers only.
Virtual functions are used to assign value dynamically,as constructors are static,so we can not make them virtual.
As a supplement, calling a virtual function of an object that has not yet completed construction will face the same problem.
For example, start a new thread in the constructor of an object, and pass the object to the new thread, if the new thread calling the virtual function of that object before the object completed construction will cause unexpected result.
For example:
#include <thread>
#include <string>
#include <iostream>
#include <chrono>
class Base
{
public:
Base()
{
std::thread worker([this] {
// This will print "Base" rather than "Sub".
this->Print();
});
worker.detach();
// Try comment out this code to see different output.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
class Sub : public Base
{
public:
void Print() override
{
std::cout << "Sub" << std::endl;
}
};
int main()
{
Sub sub;
sub.Print();
getchar();
return 0;
}
This will output:
Base
Sub
To answer what happens/why when you run that code, I compiled it via
g++ -ggdb main.cc, and stepped through with gdb.
main.cc:
class A {
public:
A() {
fn();
}
virtual void fn() { _n=1; }
int getn() { return _n; }
protected:
int _n;
};
class B: public A {
public:
B() {
// fn();
}
void fn() override {
_n = 2;
}
};
int main() {
B b;
}
Setting a break point at main, then stepping into B(), printing the this ptr, taking a step into A() (base constructor):
(gdb) step
B::B (this=0x7fffffffde80) at main2.cc:16
16 B() {
(gdb) p this
$27 = (B * const) 0x7fffffffde80
(gdb) p *this
$28 = {<A> = {_vptr.A = 0x7fffffffdf80, _n = 0}, <No data fields>}
(gdb) s
A::A (this=0x7fffffffde80) at main2.cc:3
3 A() {
(gdb) p this
$29 = (A * const) 0x7fffffffde80
shows that this initially points at the derived B obj b being constructed on the stack at 0x7fffffffde80. The next step is into the base A() ctor and this becomes A * const to the same address, which makes sense as the base A is right in the start of B object. but it still hasn't been constructed:
(gdb) p *this
$30 = {_vptr.A = 0x7fffffffdf80, _n = 0}
One more step:
(gdb) s
4 fn();
(gdb) p *this
$31 = {_vptr.A = 0x402038 <vtable for A+16>, _n = 0}
_n has been initialized, and it's virtual function table pointer contains the address of virtual void A::fn():
(gdb) p fn
$32 = {void (A * const)} 0x40114a <A::fn()>
(gdb) x/1a 0x402038
0x402038 <_ZTV1A+16>: 0x40114a <_ZN1A2fnEv>
So it makes perfect sense that the next step executes A::fn() via this->fn() given the active this and _vptr.A. Another step and we're back in B() ctor:
(gdb) s
B::B (this=0x7fffffffde80) at main2.cc:18
18 }
(gdb) p this
$34 = (B * const) 0x7fffffffde80
(gdb) p *this
$35 = {<A> = {_vptr.A = 0x402020 <vtable for B+16>, _n = 1}, <No data fields>}
The base A has been constructed. Note that address stored in the virtual function table pointer has changed to the vtable for derived class B. And so a call to fn() would select the derived class override B::fn() via this->fn() given the active this and _vptr.A (un-comment call to B::fn() in B() to see this.) Again examining 1 address stored in _vptr.A shows it now points to the derived class override:
(gdb) p fn
$36 = {void (B * const)} 0x401188 <B::fn()>
(gdb) x/1a 0x402020
0x402020 <_ZTV1B+16>: 0x401188 <_ZN1B2fnEv>
By looking at this example, and by looking at one with a 3 level inheritance, it appears that as the compiler descends to construct the base sub-objects, the type of this* and the corresponding address in _vptr.A change to reflect the current sub-object being constructed, - so it gets left pointing to the most derived type's. So we would expect virtual functions called from within ctors to choose the function for that level, i.e., same result as if they were non-virtual.. Likewise for dtors but in reverse. And this becomes a ptr to member while members are being constructed so they also properly call any virtual functions that are defined for them.
I just had this error in a program.
And I had this thinking : what happens if the method is marked as pure virtual in the constructor?
class Base {
public:
virtual int getInt() = 0;
Base(){
printf("int=%d\n", getInt());
}
};
class Derived : public Base {
public:
virtual int getInt() override {return 1;}
};
And... funny thing! You first get a warining by the compiler :
warning: pure virtual ‘virtual int Base::getInt() const’ called from constructor
And an error from ld!
/usr/bin/ld: /tmp/ccsaJnuH.o: in function `Base::Base()':
main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0x26): undefined reference to `Base::getInt()'
collect2: error: ld returned 1 exit status
This is totally illogic that you get just a warning from the compiler!
I am not seeing the importance of the virtual key word here. b is a static-typed variable, and its type is determined by compiler at compile time. The function calls would not reference the vtable. When b is constructed, its parent class's constructor is called, which is why the value of _n is set to 1.
During the object's constructor call the virtual function pointer table is not completely built. Doing this will usually not give you the behavior you expect. Calling a virtual function in this situation may work but is not guaranteed and should be avoided to be portable and follow the C++ standard.

Inheritance or Object Slicing? [duplicate]

Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
class B : public A
{
public:
B() : A() {}
virtual void fn() { _n = 2; }
};
If I write the following code:
int main()
{
B b;
int n = b.getn();
}
One might expect that n is set to 2.
It turns out that n is set to 1. Why?
Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
[...]
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
EDIT Corrected Most to All (thanks litb)
Calling a polymorphic function from a constructor is a recipe for disaster in most OO languages. Different languages will perform differently when this situation is encountered.
The basic problem is that in all languages the Base type(s) must be constructed previous to the Derived type. Now, the problem is what does it mean to call a polymorphic method from the constructor. What do you expect it to behave like? There are two approaches: call the method at the Base level (C++ style) or call the polymorphic method on an unconstructed object at the bottom of the hierarchy (Java way).
In C++ the Base class will build its version of the virtual method table prior to entering its own construction. At this point a call to the virtual method will end up calling the Base version of the method or producing a pure virtual method called in case it has no implementation at that level of the hierarchy. After the Base has been fully constructed, the compiler will start building the Derived class, and it will override the method pointers to point to the implementations in the next level of the hierarchy.
class Base {
public:
Base() { f(); }
virtual void f() { std::cout << "Base" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() {}
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d;
}
// outputs: "Base" as the vtable still points to Base::f() when Base::Base() is run
In Java, the compiler will build the virtual table equivalent at the very first step of construction, prior to entering the Base constructor or Derived constructor. The implications are different (and to my likings more dangerous). If the base class constructor calls a method that is overriden in the derived class the call will actually be handled at the derived level calling a method on an unconstructed object, yielding unexpected results. All attributes of the derived class that are initialized inside the constructor block are yet uninitialized, including 'final' attributes. Elements that have a default value defined at the class level will have that value.
public class Base {
public Base() { polymorphic(); }
public void polymorphic() {
System.out.println( "Base" );
}
}
public class Derived extends Base
{
final int x;
public Derived( int value ) {
x = value;
polymorphic();
}
public void polymorphic() {
System.out.println( "Derived: " + x );
}
public static void main( String args[] ) {
Derived d = new Derived( 5 );
}
}
// outputs: Derived 0
// Derived 5
// ... so much for final attributes never changing :P
As you see, calling a polymorphic (virtual in C++ terminology) methods is a common source of errors. In C++, at least you have the guarantee that it will never call a method on a yet unconstructed object...
The reason is that C++ objects are constructed like onions, from the inside out. Base classes are constructed before derived classes. So, before a B can be made, an A must be made. When A's constructor is called, it's not a B yet, so the virtual function table still has the entry for A's copy of fn().
The C++ FAQ Lite Covers this pretty well:
Essentially, during the call to the base classes constructor, the object is not yet of the derived type and thus the base type's implementation of the virtual function is called and not the derived type's.
One solution to your problem is using factory methods to create your object.
Define a common base class for your class hierarchy containing a virtual method afterConstruction():
class Object
{
public:
virtual void afterConstruction() {}
// ...
};
Define a factory method:
template< class C >
C* factoryNew()
{
C* pObject = new C();
pObject->afterConstruction();
return pObject;
}
Use it like this:
class MyClass : public Object
{
public:
virtual void afterConstruction()
{
// do something.
}
// ...
};
MyClass* pMyObject = factoryNew();
The C++ Standard (ISO/IEC 14882-2014) say's:
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.
So, attempting to call a derived class function from a base class under construction is dangerous.Similarly, an object is destroyed in reverse order from construction, so attempting to call a function in a more derived class from a destructor may access resources that have already been released.
As has been pointed out, the objects are created base-down upon construction. When the base object is being constructed, the derived object does not exist yet, so a virtual function override cannot work.
However, this can be solved with polymorphic getters that use static polymorphism instead of virtual functions if your getters return constants, or otherwise can be expressed in a static member function, This example uses CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
template<typename DerivedClass>
class Base
{
public:
inline Base() :
foo(DerivedClass::getFoo())
{}
inline int fooSq() {
return foo * foo;
}
const int foo;
};
class A : public Base<A>
{
public:
inline static int getFoo() { return 1; }
};
class B : public Base<B>
{
public:
inline static int getFoo() { return 2; }
};
class C : public Base<C>
{
public:
inline static int getFoo() { return 3; }
};
int main()
{
A a;
B b;
C c;
std::cout << a.fooSq() << ", " << b.fooSq() << ", " << c.fooSq() << std::endl;
return 0;
}
With the use of static polymorphism, the base class knows which class' getter to call as the information is provided at compile-time.
Do you know the crash error from Windows explorer?! "Pure virtual function call ..."
Same problem ...
class AbstractClass
{
public:
AbstractClass( ){
//if you call pureVitualFunction I will crash...
}
virtual void pureVitualFunction() = 0;
};
Because there is no implemetation for the function pureVitualFunction() and the function is called in the constructor the program will crash.
The vtables are created by the compiler.
A class object has a pointer to its vtable. When it starts life, that vtable pointer points to the vtable
of the base class. At the end of the constructor code, the compiler generates code to re-point the vtable pointer
to the actual vtable for the class. This ensures that constructor code that calls virtual functions calls the
base class implementations of those functions, not the override in the class.
Firstly,Object is created and then we assign it 's address to pointers.Constructors are called at the time of object creation and used to initializ the value of data members. Pointer to object comes into scenario after object creation. Thats why, C++ do not allows us to make constructors as virtual .
.another reason is that, There is nothing like pointer to constructor , which can point to virtual constructor,because one of the property of virtual function is that it can be used by pointers only.
Virtual functions are used to assign value dynamically,as constructors are static,so we can not make them virtual.
As a supplement, calling a virtual function of an object that has not yet completed construction will face the same problem.
For example, start a new thread in the constructor of an object, and pass the object to the new thread, if the new thread calling the virtual function of that object before the object completed construction will cause unexpected result.
For example:
#include <thread>
#include <string>
#include <iostream>
#include <chrono>
class Base
{
public:
Base()
{
std::thread worker([this] {
// This will print "Base" rather than "Sub".
this->Print();
});
worker.detach();
// Try comment out this code to see different output.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
class Sub : public Base
{
public:
void Print() override
{
std::cout << "Sub" << std::endl;
}
};
int main()
{
Sub sub;
sub.Print();
getchar();
return 0;
}
This will output:
Base
Sub
To answer what happens/why when you run that code, I compiled it via
g++ -ggdb main.cc, and stepped through with gdb.
main.cc:
class A {
public:
A() {
fn();
}
virtual void fn() { _n=1; }
int getn() { return _n; }
protected:
int _n;
};
class B: public A {
public:
B() {
// fn();
}
void fn() override {
_n = 2;
}
};
int main() {
B b;
}
Setting a break point at main, then stepping into B(), printing the this ptr, taking a step into A() (base constructor):
(gdb) step
B::B (this=0x7fffffffde80) at main2.cc:16
16 B() {
(gdb) p this
$27 = (B * const) 0x7fffffffde80
(gdb) p *this
$28 = {<A> = {_vptr.A = 0x7fffffffdf80, _n = 0}, <No data fields>}
(gdb) s
A::A (this=0x7fffffffde80) at main2.cc:3
3 A() {
(gdb) p this
$29 = (A * const) 0x7fffffffde80
shows that this initially points at the derived B obj b being constructed on the stack at 0x7fffffffde80. The next step is into the base A() ctor and this becomes A * const to the same address, which makes sense as the base A is right in the start of B object. but it still hasn't been constructed:
(gdb) p *this
$30 = {_vptr.A = 0x7fffffffdf80, _n = 0}
One more step:
(gdb) s
4 fn();
(gdb) p *this
$31 = {_vptr.A = 0x402038 <vtable for A+16>, _n = 0}
_n has been initialized, and it's virtual function table pointer contains the address of virtual void A::fn():
(gdb) p fn
$32 = {void (A * const)} 0x40114a <A::fn()>
(gdb) x/1a 0x402038
0x402038 <_ZTV1A+16>: 0x40114a <_ZN1A2fnEv>
So it makes perfect sense that the next step executes A::fn() via this->fn() given the active this and _vptr.A. Another step and we're back in B() ctor:
(gdb) s
B::B (this=0x7fffffffde80) at main2.cc:18
18 }
(gdb) p this
$34 = (B * const) 0x7fffffffde80
(gdb) p *this
$35 = {<A> = {_vptr.A = 0x402020 <vtable for B+16>, _n = 1}, <No data fields>}
The base A has been constructed. Note that address stored in the virtual function table pointer has changed to the vtable for derived class B. And so a call to fn() would select the derived class override B::fn() via this->fn() given the active this and _vptr.A (un-comment call to B::fn() in B() to see this.) Again examining 1 address stored in _vptr.A shows it now points to the derived class override:
(gdb) p fn
$36 = {void (B * const)} 0x401188 <B::fn()>
(gdb) x/1a 0x402020
0x402020 <_ZTV1B+16>: 0x401188 <_ZN1B2fnEv>
By looking at this example, and by looking at one with a 3 level inheritance, it appears that as the compiler descends to construct the base sub-objects, the type of this* and the corresponding address in _vptr.A change to reflect the current sub-object being constructed, - so it gets left pointing to the most derived type's. So we would expect virtual functions called from within ctors to choose the function for that level, i.e., same result as if they were non-virtual.. Likewise for dtors but in reverse. And this becomes a ptr to member while members are being constructed so they also properly call any virtual functions that are defined for them.
I just had this error in a program.
And I had this thinking : what happens if the method is marked as pure virtual in the constructor?
class Base {
public:
virtual int getInt() = 0;
Base(){
printf("int=%d\n", getInt());
}
};
class Derived : public Base {
public:
virtual int getInt() override {return 1;}
};
And... funny thing! You first get a warining by the compiler :
warning: pure virtual ‘virtual int Base::getInt() const’ called from constructor
And an error from ld!
/usr/bin/ld: /tmp/ccsaJnuH.o: in function `Base::Base()':
main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0x26): undefined reference to `Base::getInt()'
collect2: error: ld returned 1 exit status
This is totally illogic that you get just a warning from the compiler!
I am not seeing the importance of the virtual key word here. b is a static-typed variable, and its type is determined by compiler at compile time. The function calls would not reference the vtable. When b is constructed, its parent class's constructor is called, which is why the value of _n is set to 1.
During the object's constructor call the virtual function pointer table is not completely built. Doing this will usually not give you the behavior you expect. Calling a virtual function in this situation may work but is not guaranteed and should be avoided to be portable and follow the C++ standard.

Calling virtual functions inside constructors

Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
class B : public A
{
public:
B() : A() {}
virtual void fn() { _n = 2; }
};
If I write the following code:
int main()
{
B b;
int n = b.getn();
}
One might expect that n is set to 2.
It turns out that n is set to 1. Why?
Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
[...]
Destruction is done “derived class before base class”, so virtual functions behave as in constructors: Only the local definitions are used – and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.
EDIT Corrected Most to All (thanks litb)
Calling a polymorphic function from a constructor is a recipe for disaster in most OO languages. Different languages will perform differently when this situation is encountered.
The basic problem is that in all languages the Base type(s) must be constructed previous to the Derived type. Now, the problem is what does it mean to call a polymorphic method from the constructor. What do you expect it to behave like? There are two approaches: call the method at the Base level (C++ style) or call the polymorphic method on an unconstructed object at the bottom of the hierarchy (Java way).
In C++ the Base class will build its version of the virtual method table prior to entering its own construction. At this point a call to the virtual method will end up calling the Base version of the method or producing a pure virtual method called in case it has no implementation at that level of the hierarchy. After the Base has been fully constructed, the compiler will start building the Derived class, and it will override the method pointers to point to the implementations in the next level of the hierarchy.
class Base {
public:
Base() { f(); }
virtual void f() { std::cout << "Base" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() {}
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d;
}
// outputs: "Base" as the vtable still points to Base::f() when Base::Base() is run
In Java, the compiler will build the virtual table equivalent at the very first step of construction, prior to entering the Base constructor or Derived constructor. The implications are different (and to my likings more dangerous). If the base class constructor calls a method that is overriden in the derived class the call will actually be handled at the derived level calling a method on an unconstructed object, yielding unexpected results. All attributes of the derived class that are initialized inside the constructor block are yet uninitialized, including 'final' attributes. Elements that have a default value defined at the class level will have that value.
public class Base {
public Base() { polymorphic(); }
public void polymorphic() {
System.out.println( "Base" );
}
}
public class Derived extends Base
{
final int x;
public Derived( int value ) {
x = value;
polymorphic();
}
public void polymorphic() {
System.out.println( "Derived: " + x );
}
public static void main( String args[] ) {
Derived d = new Derived( 5 );
}
}
// outputs: Derived 0
// Derived 5
// ... so much for final attributes never changing :P
As you see, calling a polymorphic (virtual in C++ terminology) methods is a common source of errors. In C++, at least you have the guarantee that it will never call a method on a yet unconstructed object...
The reason is that C++ objects are constructed like onions, from the inside out. Base classes are constructed before derived classes. So, before a B can be made, an A must be made. When A's constructor is called, it's not a B yet, so the virtual function table still has the entry for A's copy of fn().
The C++ FAQ Lite Covers this pretty well:
Essentially, during the call to the base classes constructor, the object is not yet of the derived type and thus the base type's implementation of the virtual function is called and not the derived type's.
One solution to your problem is using factory methods to create your object.
Define a common base class for your class hierarchy containing a virtual method afterConstruction():
class Object
{
public:
virtual void afterConstruction() {}
// ...
};
Define a factory method:
template< class C >
C* factoryNew()
{
C* pObject = new C();
pObject->afterConstruction();
return pObject;
}
Use it like this:
class MyClass : public Object
{
public:
virtual void afterConstruction()
{
// do something.
}
// ...
};
MyClass* pMyObject = factoryNew();
The C++ Standard (ISO/IEC 14882-2014) say's:
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.
So, attempting to call a derived class function from a base class under construction is dangerous.Similarly, an object is destroyed in reverse order from construction, so attempting to call a function in a more derived class from a destructor may access resources that have already been released.
As has been pointed out, the objects are created base-down upon construction. When the base object is being constructed, the derived object does not exist yet, so a virtual function override cannot work.
However, this can be solved with polymorphic getters that use static polymorphism instead of virtual functions if your getters return constants, or otherwise can be expressed in a static member function, This example uses CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
template<typename DerivedClass>
class Base
{
public:
inline Base() :
foo(DerivedClass::getFoo())
{}
inline int fooSq() {
return foo * foo;
}
const int foo;
};
class A : public Base<A>
{
public:
inline static int getFoo() { return 1; }
};
class B : public Base<B>
{
public:
inline static int getFoo() { return 2; }
};
class C : public Base<C>
{
public:
inline static int getFoo() { return 3; }
};
int main()
{
A a;
B b;
C c;
std::cout << a.fooSq() << ", " << b.fooSq() << ", " << c.fooSq() << std::endl;
return 0;
}
With the use of static polymorphism, the base class knows which class' getter to call as the information is provided at compile-time.
Do you know the crash error from Windows explorer?! "Pure virtual function call ..."
Same problem ...
class AbstractClass
{
public:
AbstractClass( ){
//if you call pureVitualFunction I will crash...
}
virtual void pureVitualFunction() = 0;
};
Because there is no implemetation for the function pureVitualFunction() and the function is called in the constructor the program will crash.
The vtables are created by the compiler.
A class object has a pointer to its vtable. When it starts life, that vtable pointer points to the vtable
of the base class. At the end of the constructor code, the compiler generates code to re-point the vtable pointer
to the actual vtable for the class. This ensures that constructor code that calls virtual functions calls the
base class implementations of those functions, not the override in the class.
Firstly,Object is created and then we assign it 's address to pointers.Constructors are called at the time of object creation and used to initializ the value of data members. Pointer to object comes into scenario after object creation. Thats why, C++ do not allows us to make constructors as virtual .
.another reason is that, There is nothing like pointer to constructor , which can point to virtual constructor,because one of the property of virtual function is that it can be used by pointers only.
Virtual functions are used to assign value dynamically,as constructors are static,so we can not make them virtual.
As a supplement, calling a virtual function of an object that has not yet completed construction will face the same problem.
For example, start a new thread in the constructor of an object, and pass the object to the new thread, if the new thread calling the virtual function of that object before the object completed construction will cause unexpected result.
For example:
#include <thread>
#include <string>
#include <iostream>
#include <chrono>
class Base
{
public:
Base()
{
std::thread worker([this] {
// This will print "Base" rather than "Sub".
this->Print();
});
worker.detach();
// Try comment out this code to see different output.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
virtual void Print()
{
std::cout << "Base" << std::endl;
}
};
class Sub : public Base
{
public:
void Print() override
{
std::cout << "Sub" << std::endl;
}
};
int main()
{
Sub sub;
sub.Print();
getchar();
return 0;
}
This will output:
Base
Sub
To answer what happens/why when you run that code, I compiled it via
g++ -ggdb main.cc, and stepped through with gdb.
main.cc:
class A {
public:
A() {
fn();
}
virtual void fn() { _n=1; }
int getn() { return _n; }
protected:
int _n;
};
class B: public A {
public:
B() {
// fn();
}
void fn() override {
_n = 2;
}
};
int main() {
B b;
}
Setting a break point at main, then stepping into B(), printing the this ptr, taking a step into A() (base constructor):
(gdb) step
B::B (this=0x7fffffffde80) at main2.cc:16
16 B() {
(gdb) p this
$27 = (B * const) 0x7fffffffde80
(gdb) p *this
$28 = {<A> = {_vptr.A = 0x7fffffffdf80, _n = 0}, <No data fields>}
(gdb) s
A::A (this=0x7fffffffde80) at main2.cc:3
3 A() {
(gdb) p this
$29 = (A * const) 0x7fffffffde80
shows that this initially points at the derived B obj b being constructed on the stack at 0x7fffffffde80. The next step is into the base A() ctor and this becomes A * const to the same address, which makes sense as the base A is right in the start of B object. but it still hasn't been constructed:
(gdb) p *this
$30 = {_vptr.A = 0x7fffffffdf80, _n = 0}
One more step:
(gdb) s
4 fn();
(gdb) p *this
$31 = {_vptr.A = 0x402038 <vtable for A+16>, _n = 0}
_n has been initialized, and it's virtual function table pointer contains the address of virtual void A::fn():
(gdb) p fn
$32 = {void (A * const)} 0x40114a <A::fn()>
(gdb) x/1a 0x402038
0x402038 <_ZTV1A+16>: 0x40114a <_ZN1A2fnEv>
So it makes perfect sense that the next step executes A::fn() via this->fn() given the active this and _vptr.A. Another step and we're back in B() ctor:
(gdb) s
B::B (this=0x7fffffffde80) at main2.cc:18
18 }
(gdb) p this
$34 = (B * const) 0x7fffffffde80
(gdb) p *this
$35 = {<A> = {_vptr.A = 0x402020 <vtable for B+16>, _n = 1}, <No data fields>}
The base A has been constructed. Note that address stored in the virtual function table pointer has changed to the vtable for derived class B. And so a call to fn() would select the derived class override B::fn() via this->fn() given the active this and _vptr.A (un-comment call to B::fn() in B() to see this.) Again examining 1 address stored in _vptr.A shows it now points to the derived class override:
(gdb) p fn
$36 = {void (B * const)} 0x401188 <B::fn()>
(gdb) x/1a 0x402020
0x402020 <_ZTV1B+16>: 0x401188 <_ZN1B2fnEv>
By looking at this example, and by looking at one with a 3 level inheritance, it appears that as the compiler descends to construct the base sub-objects, the type of this* and the corresponding address in _vptr.A change to reflect the current sub-object being constructed, - so it gets left pointing to the most derived type's. So we would expect virtual functions called from within ctors to choose the function for that level, i.e., same result as if they were non-virtual.. Likewise for dtors but in reverse. And this becomes a ptr to member while members are being constructed so they also properly call any virtual functions that are defined for them.
I just had this error in a program.
And I had this thinking : what happens if the method is marked as pure virtual in the constructor?
class Base {
public:
virtual int getInt() = 0;
Base(){
printf("int=%d\n", getInt());
}
};
class Derived : public Base {
public:
virtual int getInt() override {return 1;}
};
And... funny thing! You first get a warining by the compiler :
warning: pure virtual ‘virtual int Base::getInt() const’ called from constructor
And an error from ld!
/usr/bin/ld: /tmp/ccsaJnuH.o: in function `Base::Base()':
main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0x26): undefined reference to `Base::getInt()'
collect2: error: ld returned 1 exit status
This is totally illogic that you get just a warning from the compiler!
I am not seeing the importance of the virtual key word here. b is a static-typed variable, and its type is determined by compiler at compile time. The function calls would not reference the vtable. When b is constructed, its parent class's constructor is called, which is why the value of _n is set to 1.
During the object's constructor call the virtual function pointer table is not completely built. Doing this will usually not give you the behavior you expect. Calling a virtual function in this situation may work but is not guaranteed and should be avoided to be portable and follow the C++ standard.