I'm sure this is a really simple question. The following code shows what I'm trying to do:
class MemberClass {
public:
MemberClass(int abc){ }
};
class MyClass {
public:
MemberClass m_class;
MyClass(int xyz) {
if(xyz == 42)
m_class = MemberClass(12);
else
m_class = MemberClass(32);
}
};
This doesn't compile, because m_class
is being created with an empty constructor (which doesn't exist). What is the right way of doing this? My guess is using pointers and instantiating m_class
using new
, but I'm hoping there is an easier way.
Edit: I should have said earlier, but my actual problem has an additional complication: I need to call a method before initializing m_class, in order to set up the environment. So:
class MyClass {
public:
MemberClass m_class;
MyClass(int xyz) {
do_something(); // this must happen before m_class is created
if(xyz == 42)
m_class = MemberClass(12);
else
m_class = MemberClass(32);
}
};
Is it possible to achieve this with fancy initialization list tricks?
To answer your revised question, that get a bit tricky. The simplest way would be to make
m_class
a pointer. If you really want it as a data member, then you have to get creative. Create a new class (it's best if it's defined internal to MyClass). Have it's ctor be the function that needs to be called. Include it first among the declarations of data members (this will make it the first instaniated).Try this:
This gives it a default value, and your default constructor.
To have the initialization happen after other stuff happens, you do indeed need to use pointers, something like this:
The only difference is that you'll need to access member variables as
m_pClass->counter
instead ofm_class.counter
, anddelete m_pClass
in the destructor.Use the conditional operator. If the expression is larger, use a function
To call a function before initializing m_class, you can place a struct before that member and leverage RAII
This will call
do_something()
before initializingm_class
. Note that you are not allowed to call non-static member functions ofMyClass
before the constructor initializer list has completed. The function would have to be a member of its base class and the base class' ctor must already be completed for that to work.Also note that the function, of course, is always called, for each separate object created - not only for the first object created. If you want to do that, you could create a static variable within the initializer's constructor:
It's using the comma operator. Note that you can catch any exception thrown by
do_something
by using a function-try blockThe
do_something
function will be called again next time, if it threw that exception that caused theMyClass
object fail to be created. Hope this helps :)Or:
If you somehow still want to keep the same syntax. Member initalization is more efficient though.
Use the initializer list syntax:
Probably cleaner with a factory: