can you try making that function static.
Main Topics
Browse All TopicsI have a slight problem that one of the members of my constructor's initializer list uses the output from a member function that in return requires another member to be initialized.
The function is always called before the initializers are assigned so the required member data is not available at this time. Is there any way of ensuring that the member I require is initialized before the function call? I understand that initialisation order is controlled by the order in which members are declared - can this be made to apply to functions?
See the example code below where CMyClass is derived from CBaseClass:
class CBaseClass
{
public:
CBaseClass(int i)
{
// do something with an int
}
virtual ~CBaseClass(){}
}
class CMyClass : public CBaseClass
{
public:
CMyClass( CData* pData )
: m_pData(pData),
CBaseClass( ExtractIntFromData() )
{
}
private:
int ExtracttIntFromData()
{
// Do some process on m_pData returning an int
return m_pData->GetInt() * 5;
}
CData* m_pData;
}
The constructor for CBaseClass takes an int. When CMyClass is constructed, it would be nice to use the existing member function ExtracttIntFromData() to calculate the required int. However this function relies on the member m_pData being initialised prior to the function call.
ExtractIntFromData() is always called prior to initialisation so will crash, is there any way of forcing the initialisation prior to the function call?
Obviously in this example ExtractIntFromData() could be refactored to take CData* as a parameter but I'm curious as to whether the code could be made to work as is.
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
I'm not sure I understand your explanation.
I think you can solve the problem if you will:
1. Add a function Set into CBaseClass and instead of using a constructor with the integer as a parameter, you will call this Set method from CMyClass constructor.
2. use the aggregation:
class CMyClass
{
CBaseClass m_Base
}
so in CMyClass constructor you can arrange things as you wish.
Probably, I'd use a template. Maybe as it is the attached code.
The base class is constructed before the derived class so trying to call a member of the derived class to initialize the base class will result in undefined behaviour. You are trying to call a member on a class that has not been constructed. This behaviour is immutable. This will only work if the member function is static otherwise all bets are off.
That is why I originally suggested moving the functionality into the 'data' class. (Sounds like a design problem here)
A possible alternative? - really depends on what the function actually does and requires to do its stuff.
CMyClass( CData* pData )
: m_pData(pData),
CBaseClass( ExtractIntFromData(pData) )
{
}
int CMyClass::ExtractIntFromDa
int CMyClass::ExtractIntFromDa
{ now do the real stuff here };
You can, of course, separate construction and initialisation into two steps. Have the base class default construct with sensible values (even though they aren't the ones you want at this stage) and add an initialise member, which can be called by your derived class in your derived classes constructor (where you can call any member function safely except virtual ones), which can be used to initialise your base class.
Thanks for the comments people, some very useful stuff there.
Its worth knowing that at member initialisation time, no assumptions can be made about the integrity of the class being initialised.
I agree with AndyAinscow, usually when you start messing around at the borders of C++ language constraints its a good hint there is a design problem!
Good suggestion to aggregate as opposed to inherit, although in my real world case I need the polymorphism inheritance gives.
In the context of the real code this example was based on, I think ExtractIntFromData() does really belong as a member of CDerivedClass. Therefore the most appropriate solution for my real world problem is to have 2 ExtractIntFromData() functions, one that is static and takes CData as a parameter for use in the constructor. The other simply calls the first passing m_pData.
evilrix - thanks its useful to confirm that it is safe to use non-virtual member functions within a constructor.
I wrote this code initially because I believed you could use them safely within the constructor. However my mistake was in thinking the member initializer list counted as 'within' the constructor.
Business Accounts
Answer for Membership
by: Let_Me_BePosted on 2009-11-07 at 09:24:43ID: 25767151
Calling members in the initialization list has undefined behavior.