Sign in to follow this  

Call a pure virtual member function in base class constructor

This topic is 2491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a small class heirarchy with an abstract base class and I want to have a member function initialise() that automatically gets called whenever an object inheriting from this base class is constructed.

No problem, put a call to it in the base class constructor you say.

However, this initialise function will be different for all derived classes and there's not really a default implementation that makes any kind of sense, so I want to force derived classes to override it and provide their own implementation. Making it virtual means the overridden version will be called when a derived class is created but if I make it pure virtual to force the derived classes to override it I get an unresolved external symbol error.

Is there any way of doing this? Have a virtual function be called by the base class constructor (so it gets called automatically when the object is created), but force derived classes to provide their own implementation?

Share this post


Link to post
Share on other sites
[quote]

[color=#1C2837][size=2]Is there any way of doing this? Have a virtual function be called by the base class constructor (so it gets called automatically when the object is created), but force derived classes to provide their own implementation? [/quote][/size][/color]
[color=#1C2837][size=2][/size][/color]When you look at the facts you can see the problem. At the point you want to call into a virtual function of a derived class the derived class does not exist.
Why do you want an initialise function to be called on construction of a base class for a derived class? What is wrong with using the constructor of the derived type?

Share this post


Link to post
Share on other sites
[quote name='BattleMetalChris' timestamp='1297903104' post='4775191']
I have a small class heirarchy with an abstract base class and I want to have a member function initialise() that automatically gets called whenever an object inheriting from this base class is constructed.

No problem, put a call to it in the base class constructor you say.

However, this initialise function will be different for all derived classes and there's not really a default implementation that makes any kind of sense, so I want to force derived classes to override it and provide their own implementation. Making it virtual means the overridden version will be called when a derived class is created but if I make it pure virtual to force the derived classes to override it I get an unresolved external symbol error.

Is there any way of doing this? Have a virtual function be called by the base class constructor (so it gets called automatically when the object is created), but force derived classes to provide their own implementation?
[/quote]

Well the problem here is that while the constructor is executed the class is not fully constructed yet.
Since normally you have this behaviour for stuff that is created by factor or someting you can simply call the init function after the class is constructed. that way you can also be sure the class is fully constructed while calling the init function.

Share this post


Link to post
Share on other sites
Can you not just forget about the virtual initialise() function and have each derived class do whatever in their respective constructors? This is an entirely "normal" way of doing things, I'd say.

FWIW, you can't call virtual functions of a class in its own constructor or destructor anyway. It's undefined behaviour. There's no guarantee that the virtual table (or equivalent) will be in place by the beginning of construction, or won't have been torn down before the destructor call is made.

Share this post


Link to post
Share on other sites
[quote name='edd²' timestamp='1297906196' post='4775215']
FWIW, you can't call virtual functions of a class in its own constructor or destructor anyway.
[/quote]
Yes you can. Section 12.7 paragraph 3 of the C++ standard begins:
[quote]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 (including from the mem-initializer for a data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor's own class or in one of its bases, but not a function overriding it in a class derived from the constructor or destructor's class, or overriding it in one of the other base classes of the most derived object (1.8).[/quote]

Share this post


Link to post
Share on other sites
Ah, thanks.

So the advice should perhaps be modified to say: "calling a the virtual function in your base class' constructor probably won't do what you want, in this instance at least".

EDIT: I'm guessing a compiler isn't required to issue a diagnostic when calling a pure virtual function in the base class ctor/dtor? I think the source of my assumption was having seen a few "pure virtual function called" message boxes in the past.

Share this post


Link to post
Share on other sites
[quote name='edd²' timestamp='1297907378' post='4775226']
EDIT: I'm guessing a compiler isn't required to issue a diagnostic when calling a pure virtual function in the base class ctor/dtor? I think the source of my assumption was having seen a few "pure virtual function called" message boxes in the past.
[/quote]
No, calling a pure virtual function inside a constructor or destructor is undefined behavior, and undefined behavior has no requirements on the implementation to issue any sort of diagnostic message. In practice, most compilers will generate a runtime error and try very hard to catch such an issue at compile time, but they aren't required to do so.

Share this post


Link to post
Share on other sites

This topic is 2491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this