This question already has answers here:
Calling virtual functions inside constructors
(15 answers)
Closed 6 years ago.
Why the following example prints "0" and what must change for it to print "1" as I expected ?
#include <iostream>
struct base {
virtual const int value() const {
return 0;
}
base() {
std::cout << value() << std::endl;
}
virtual ~base() {}
};
struct derived : public base {
virtual const int value() const {
return 1;
}
};
int main(void) {
derived example;
}
Because base is constructed first and hasn't "matured" into a derived yet. It can't call methods on an object when it can't guarantee that the object is already properly initialized.
When a derived object is being constructed, before the body of the derived class constructor is called the base class constructor must complete. Before the derived class constructor is called the dynamic type of the object under construction is a base class instance and not a derived class instance. For this reason, when you call a virtual function from a constructor, only the base class virtual function overrides can be called.
Actually, there is a way to get this behavior. "Every problem in software can be solved with a level of indirection."
/* Disclaimer: I haven't done C++ in many months now, there might be a few syntax errors here and there. */
class parent
{
public:
parent( ) { /* nothing interesting here. */ };
protected:
struct parent_virtual
{
virtual void do_something( ) { cout << "in parent."; }
};
parent( const parent_virtual& obj )
{
obj.do_something( );
}
};
class child : public parent
{
protected:
struct child_virtual : public parent_virtual
{
void do_something( ) { cout << "in child."; }
};
public:
child( ) : parent( child_virtual( ) ) { }
};
The question of how it works is a FAQ item.
Summarizing, while class T is being constructed, the dynamic type is T, which prevents virtual calls to derived class function implementations, which if permitted could execute code before the relevant class invariant had been established (a common problem in Java and C#, but C++ is safe in this respect).
The question of how to do derived class specific initialization in a base class constructor is also a FAQ item, directly following the previously mentioned one.
Summarizing, using static or dynamic polymorphism on may pass the relevant function implementations up to the base class constructor (or class).
One particular way to do that is to pass a “parts factory” object up, where this argument can be defaulted. For example, a general Button class might pass a button creation API function up to its Widget base class constructor, so that that constructor can create the correct API level object.
You should not polymorphically call the virtual methods from constructor.
Instead you can call them after construction of object.
Your code can be re written as follows
struct base {
virtual const int value() const {
return 0;
}
base() {
/* std::cout << value() << std::endl; */
}
virtual ~base() {}
};
struct derived : public base {
virtual const int value() const {
return 1;
}
};
int main(void) {
derived example;
std::cout << example.value() << std::endl;
}
The general rule is you don't call a virtual function from a constructor.
In C++, you cannot call a virtual / overriden method from a constructor.
Now, there is a good reason you can do this. As a "best practice in software", you should avoid calling additional methods from your constructor, even non virtual, as possible.
But, there is always an exception to the rule, so you may want to use a "pseudo constructor method", to emulate them:
#include <iostream>
class base {
// <constructor>
base() {
// do nothing in purpouse
}
// </constructor>
// <destructor>
~base() {
// do nothing in purpouse
}
// </destructor>
// <fake-constructor>
public virtual void create() {
// move code from static constructor to fake constructor
std::cout << value() << std::endl;
}
// </fake-constructor>
// <fake-destructor>
public virtual void destroy() {
// move code from static destructor to fake destructor
// ...
}
// </fake-destructor>
public virtual const int value() const {
return 0;
}
public virtual void DoSomething() {
// std:cout << "Hello World";
}
};
class derived : public base {
// <fake-constructor>
public override void create() {
// move code from static constructor to fake constructor
std::cout << "Im pretending to be a virtual constructor," << std::endl;
std::cout << "and can call virtual methods" << std::endl;
}
// </fake-constructor>
// <fake-destructor>
public override void destroy() {
// move code from static destructor to fake destructor
std::cout << "Im pretending to be a virtual destructor," << std::endl;
std::cout << "and can call virtual methods" << std::endl;
}
// </fake-destructor>
public virtual const int value() const {
return 1;
}
};
int main(void) {
// call fake virtual constructor in same line, after real constructor
derived* example = new example(); example->create();
// do several stuff with your objects
example->doSomething();
// call fake virtual destructor in same line, before real destructor
example->destroy(); delete example();
}
As a plus, I recommend programmers to use "struct" for only fields structures, and "class" for structures with fields, methods, constructors, ...
Related
Suppose I have
struct C {
C() { init(); };
void init() { cout << "C" << endl; };
};
struct D : public C {
D() : C() { };
void init() { cout << "D" << endl; }
};
D();
why I get "C" printed? How can change this behaviour (and get "D").
How if I want both?
why I get "C" printed?
C::init() is not declared as virtual, so D cannot override it. But even if C::init() were declared as virtual, D::init() would still not be called when init() is called inside of C's constructor.
C++ constructs base classes before derived classes (and destructs derived clases before base classes). So C's constructor runs before D is constructed (and C's destructor runs after D is destructed). The VMT of the object being constructed/destructed simply does not point at D's method table when C is being constructed/destructed, it points at C's method table instead.
How can change this behaviour (and get "D").
You cannot call a derived virtual method from inside of a base class constructor/destructor. The VMT does not contain a pointer to the derived class method table at those stages.
You have a quite fundamental problem here: You want to call a member function of a derived class on an object that does not exist yet.
Remember that objects are constructed by first constructing the base sub-object and then the derived object. So even if you'd manage to apply a “clever” trick to actually invoke the derived class' init function, as soon as that function would try to access any data member of the derived object, it would cause arbitrary damage. On the other hand, it is fine to access only the base object, as long as you don't rely on any invariant that the constructor has not established yet. Therefore, if you don't need access to the derived object's data, you can make the init function static and pass it a reference to the base class object.
Maybe this is coming close to what you are trying to do.
#include <iostream>
struct Base
{
Base(void (*fp)(Base&) = Base::init) { fp(*this); }
static void init(Base&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Derived : Base
{
Derived() : Base(Derived::init) { }
static void init(Base&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
int
main()
{
Base b {};
std::cout << std::endl;
Derived d {};
}
Output:
static void Base::init(Base&)
static void Derived::init(Base&)
Here, the base class constructor takes a function pointer to an initializer function that takes a reference to a Base object. The function defaults to Base::init but derived classes can replace it. Be aware, however, that in this design, the Base class constructor may not safely assume that any side effect of Base::init actually took place. It is fine as an extension mechanism (if Base::init does nothing or is disposable), though.
But I doubt that you need to use this kind of machinery. If all you want to do – and this should be the normal case – is to first initialize the base object and then the derived object, C++ already will do the right thing by default if you simply call the functions from the respective constructors.
struct Base
{
Base() { this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Derived : Base
{
Derived() { this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
// main() as above ...
Output:
void Base::init()
void Base::init()
void Derived::init()
And if we only want to call the most derived class' init function, we can simply tell the base class not to run its own.
struct Base
{
Base(const bool initialize = true) { if (initialize) this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Derived : Base
{
Derived() : Base(false) { this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
// main() as above ...
Output:
void Base::init()
void Derived::init()
You only can remove init() from C constructor to not print "C".
To also print "D" add init() in D() constructor.
If for some cases you want print "C" or "D" and in some don't do something like this
struct C {
C() { };
void init() { cout << "C" << endl; };
};
struct D : public C {
D() : C()
{
if(some condition)
C::init();
if(some condition)
init();
};
void init() { cout << "D" << endl; }
};
D();
I am looking for a way to create a method that has to be implemented by every subclass. I also want the subclass to call this method on construction.
It should not be possible to call this method again after class construction..
#include <iostream>
class Base {
public:
Base() {init();}
private:
virtual void init() = 0;
};
class DerivedA : public Base {
public:
DerivedA() {}
private:
virtual void init() { std::cout << "Hello, I am A.";}
};
class DerivedB : public Base{
public:
DerivedB() {}
private:
virtual void init() {std::cout << "Hello, I am B.";}
};
int main(){
DerivedA a;
DerivedB b;
return 0;
}
This is an example, but it is not valid, because it calls a pure virtual method in constructor. Of course I can add init() in every subclass-constructor, but then it can be forgotten on new subclasses.
What is the C++ way of doing this?
The C++ way is to not do this. Init functions are bad. Simply use the constructors.
AFAIK, it is very dangerous to call virtual functions in constructors. Here is a simple example. I slightly modified your code to have init method also implemented in Base class :
#include <iostream>
#include <exception>
class Base {
protected:
Base() {init() ; }
virtual void init() {
std::cout << "Init base" << std::endl;
}
public:
void callinit() {
init();
}
};
class DerivedA : public Base {
public:
DerivedA() {}
protected:
virtual void init() { std::cout << "Hello, I am A."<< std::endl;}
};
class DerivedB : public Base{
public:
DerivedB() {}
protected:
virtual void init() {std::cout << "Hello, I am B."<< std::endl;}
};
int main(){
DerivedA a;
DerivedB b;
a.callinit();
b.callinit();
return 0;
}
and the output is :
Init base
Init base
Hello, I am A.
Hello, I am B.
What can we conclude of that :
once the object is constructed, all is fine and when we call init method we normaly get the correct implementation from derived class
but in constructor, the order is :
call Base constructor
call init method from Base object (since derived object in not still constructed)
call DerivedX constructor
So the method is always the one from Base which is definitively not what you expected.
As the other poster said, you should probably stay away from this, but the easiest example would be to make a public, non-virtual interface method on Base called Init() that must be called after the object is constructed. That method can call a pure-virtual "DoInit" method on the derived classes, and track whether or not it has been called yet with an internal flag.
I don't recommend this, but it will work.
class Base
{
public:
void Init()
{
if(!initialized)
{
DoInit();
initialized = true;
}
}
protected:
virtual void DoInit() = 0; // derived classes need to implement this
private:
bool initialized {false};
};
I faced similar problem and could not find a simple solution. I had to make the initialization in a separate class. An object of this class can be passed to Base/Derive constructors, or this class can be a template parameter.
class Initializer {
. . .
}
class Base {
public:
Base(Initializer* initializer) {
// Get members from initializer
}
}
Or:
template<Initializer TInitializer>
class Base<TInitializer> {
public:
Base() {
TInitializer initializer;
// Get members from initializer
}
}
Sorry, I did not write in C++ too long, so I could prevent some syntax errors.
C++11's call_once gets you most of the way, but it has costs.
The class will not be movable nor copyable.
You must add an extra line in every function that requires the initialization.
It does not prevent the method from being called more than once, but that is easy to add.
#include <iostream>
#include <mutex>
struct Base {
Base() {
std::cout << "Base ctor" << std::endl;
}
void sampleFunction1() {
// this line must be at the start of every function that needs the initialization
std::call_once(initedFlag, &Base::v_init, this);
std::cout << "Base::sampleFunction1" << std::endl;
}
void sampleFunction2() {
// this line must be at the start of every function that needs the initialization
std::call_once(initedFlag, &Base::v_init, this);
std::cout << "Base::sampleFunction2" << std::endl;
}
private:
virtual void v_init() = 0;
std::once_flag initedFlag;
};
Notice that the Derived class has nothing special, except that it provides v_init.
struct Derived : Base {
Derived() {
std::cout << "Derived ctor" << std::endl;
}
private:
void v_init() override {
std::cout << "Derived::v_init" << std::endl;
}
};
Demo code
int main(int argc, const char * argv[]) {
Derived d1;
Derived d2;
std::cout << "Calling d1" << std::endl;
d1.sampleFunction1();
d1.sampleFunction2();
std::cout << "Calling d2" << std::endl;
d2.sampleFunction2();
d2.sampleFunction1();
return 0;
}
Output: Notice that v_init will be called which ever sample function is called first and is not called in the ctors.
Base ctor
Derived ctor
Base ctor
Derived ctor
Calling d1
Derived::v_init
Base::sampleFunction1
Base::sampleFunction2
Calling d2
Derived::v_init
Base::sampleFunction2
Base::sampleFunction1
Consider a base class class Base which has a function virtual void foo(void). This function is implemented in Base; i.e. is not pure virtual.
Is there a pattern I can use which when inheriting from this class, i.e. class Child : public Base, compels me to override foo?
Other than making it a pure virtual function, there is no way to make the override required.
Note that the fact that a function is marked pure virtual does not mean that it cannot have an implementation in the base class - it means only that the derived class must override it.
struct Base {
virtual void foo() = 0; // foo() is pure virtual
};
struct Derived : public Base {
void foo() { // Derived overrides the pure virtual
cout << "Hello ";
Base::foo(); // Call the implementation in the base
cout << endl;
}
};
void Base::foo() {
cout << " world";
}
int main() {
Derived d;
d.foo();
return 0;
}
This prints "Hello world", with the "world" part coming from the implementation in the base class.
Demo.
C++11 introduced the override keyword to help with this:
struct Base
{
void foo();
};
struct Derived : Base
{
void foo() override; // error! Base::foo is not virtual
};
However you can not write this in Base itself to get the same effect; i.e. there is no mustoverride specifier. Ultimately, it is none of Base's business as to what derived classes do or don't override.
You can keep Base abstract whilst providing a "default" definition for your pure virtual functions:
struct Base
{
virtual void foo() = 0;
};
void Base::foo() {}
struct Derived : Base {}; // error! does not override Base::foo
struct Derived2: Base
{
virtual void foo() override
{
Base::foo(); // invokes "default" definition
}
};
This will be an acceptable solution if you are content for the entire base type to be rendered uninstantiable.
A pure-virtual member function can still have a body. The only caveat is that it must be defined outside the class definition. This is perfectly legal C++:
#include <iostream>
struct Base
{
virtual void foo() const = 0;
};
void Base::foo() const
{
std::cout << "Base!\n";
}
struct Derived : Base
{
// Uncomment following line to remove error:
//virtual void foo() const override { std::cout << "Derived\n"; Base::foo(); }
};
int main()
{
Derived d;
d.foo();
}
Live example
Notice that this makes Base an abstract class in all respects, i.e. it's impossible to instantiate Base directly.
Yes, actually there is:
#include <iostream>
class Base
{
public:
virtual void someFun() {std::cout << "Base::fun" << std::endl;}
virtual ~Base() {}
};
class AlmostBase : public Base
{
public:
virtual void someFun() = 0;
};
class Derived : public AlmostBase
{
public:
virtual void someFun() {std::cout << "Derived::fun" << std::endl;}
};
int main()
{
Derived *d = new Derived();
d->someFun();
delete d;
}
If you uncomment the someFun from Derived the compiler will complain ...
You introduce an intermediary class AlmostBase which has the function as pure virtual. This way you can have Base objects too, and the only drawback now is that all your classes will need to inherit from the intermediary base.
you can make the base method throw an exception when called, then the class must override it to avoid the parent execution.
this is used in the MFC FrameWork for example
// Derived class is responsible for implementing these handlers
// for owner/self draw controls (except for the optional DeleteItem)
void CComboBox::DrawItem(LPDRAWITEMSTRUCT)
{ ASSERT(FALSE); }
void CComboBox::MeasureItem(LPMEASUREITEMSTRUCT)
{ ASSERT(FALSE); }
int CComboBox::CompareItem(LPCOMPAREITEMSTRUCT)
{ ASSERT(FALSE); return 0; }
those methods must be inherited if the control is owner drawn it is responsible for the measuer, draw,... if you missed it while you are testing the function you will get an assert or exception with useful information thrown.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling virtual functions inside constructors
main.cpp
#include <iostream>
class BaseClass {
public:
BaseClass() {
init();
}
virtual ~BaseClass() {
deinit();
}
virtual void init() {
std::cout << "BaseClass::init()\n";
}
virtual void deinit() {
std::cout << "BaseClass::deinit()\n";
}
};
class SubClass : public BaseClass {
public:
virtual void init() {
std::cout << "SubClass::init()\n";
}
virtual void deinit() {
std::cout << "SubClass::deinit()\n";
}
};
int main() {
SubClass* cls = new SubClass;
delete cls;
return 0;
}
Why is init() and deinit() not properly overriden and the BaseClasses' methods are called instead of the SubClasses ones? What are the requirements to make it work?
BaseClass::init()
BaseClass::deinit()
Because you are calling a virtual method inside a constructor. While constructing Base class the derived one (SubClass) isn't still constructed, so actually it doesn't still exist.
It's generally a good practice to avoid calling virtual methods inside constructors.
They are overridden just fine.
But you've invoked them from the base constructor, and when the base constructor is executing, the derived part of the object does not yet exist.
So this is a largely a safety feature, and it's mandated by the C++ standard.
This question already has answers here:
Calling virtual functions inside constructors
(15 answers)
Closed 6 years ago.
Why the following example prints "0" and what must change for it to print "1" as I expected ?
#include <iostream>
struct base {
virtual const int value() const {
return 0;
}
base() {
std::cout << value() << std::endl;
}
virtual ~base() {}
};
struct derived : public base {
virtual const int value() const {
return 1;
}
};
int main(void) {
derived example;
}
Because base is constructed first and hasn't "matured" into a derived yet. It can't call methods on an object when it can't guarantee that the object is already properly initialized.
When a derived object is being constructed, before the body of the derived class constructor is called the base class constructor must complete. Before the derived class constructor is called the dynamic type of the object under construction is a base class instance and not a derived class instance. For this reason, when you call a virtual function from a constructor, only the base class virtual function overrides can be called.
Actually, there is a way to get this behavior. "Every problem in software can be solved with a level of indirection."
/* Disclaimer: I haven't done C++ in many months now, there might be a few syntax errors here and there. */
class parent
{
public:
parent( ) { /* nothing interesting here. */ };
protected:
struct parent_virtual
{
virtual void do_something( ) { cout << "in parent."; }
};
parent( const parent_virtual& obj )
{
obj.do_something( );
}
};
class child : public parent
{
protected:
struct child_virtual : public parent_virtual
{
void do_something( ) { cout << "in child."; }
};
public:
child( ) : parent( child_virtual( ) ) { }
};
The question of how it works is a FAQ item.
Summarizing, while class T is being constructed, the dynamic type is T, which prevents virtual calls to derived class function implementations, which if permitted could execute code before the relevant class invariant had been established (a common problem in Java and C#, but C++ is safe in this respect).
The question of how to do derived class specific initialization in a base class constructor is also a FAQ item, directly following the previously mentioned one.
Summarizing, using static or dynamic polymorphism on may pass the relevant function implementations up to the base class constructor (or class).
One particular way to do that is to pass a “parts factory” object up, where this argument can be defaulted. For example, a general Button class might pass a button creation API function up to its Widget base class constructor, so that that constructor can create the correct API level object.
You should not polymorphically call the virtual methods from constructor.
Instead you can call them after construction of object.
Your code can be re written as follows
struct base {
virtual const int value() const {
return 0;
}
base() {
/* std::cout << value() << std::endl; */
}
virtual ~base() {}
};
struct derived : public base {
virtual const int value() const {
return 1;
}
};
int main(void) {
derived example;
std::cout << example.value() << std::endl;
}
The general rule is you don't call a virtual function from a constructor.
In C++, you cannot call a virtual / overriden method from a constructor.
Now, there is a good reason you can do this. As a "best practice in software", you should avoid calling additional methods from your constructor, even non virtual, as possible.
But, there is always an exception to the rule, so you may want to use a "pseudo constructor method", to emulate them:
#include <iostream>
class base {
// <constructor>
base() {
// do nothing in purpouse
}
// </constructor>
// <destructor>
~base() {
// do nothing in purpouse
}
// </destructor>
// <fake-constructor>
public virtual void create() {
// move code from static constructor to fake constructor
std::cout << value() << std::endl;
}
// </fake-constructor>
// <fake-destructor>
public virtual void destroy() {
// move code from static destructor to fake destructor
// ...
}
// </fake-destructor>
public virtual const int value() const {
return 0;
}
public virtual void DoSomething() {
// std:cout << "Hello World";
}
};
class derived : public base {
// <fake-constructor>
public override void create() {
// move code from static constructor to fake constructor
std::cout << "Im pretending to be a virtual constructor," << std::endl;
std::cout << "and can call virtual methods" << std::endl;
}
// </fake-constructor>
// <fake-destructor>
public override void destroy() {
// move code from static destructor to fake destructor
std::cout << "Im pretending to be a virtual destructor," << std::endl;
std::cout << "and can call virtual methods" << std::endl;
}
// </fake-destructor>
public virtual const int value() const {
return 1;
}
};
int main(void) {
// call fake virtual constructor in same line, after real constructor
derived* example = new example(); example->create();
// do several stuff with your objects
example->doSomething();
// call fake virtual destructor in same line, before real destructor
example->destroy(); delete example();
}
As a plus, I recommend programmers to use "struct" for only fields structures, and "class" for structures with fields, methods, constructors, ...