Suppose I have a class A without a default constructor, a factory method factoryA that returns an object of type A, and a class B that has A as its member. I know that in this case the member of type A of B has to be initialize in B's constructor initialization list. It is not entirely clear to me why so if someone could explain that to me it would be great. Also, what if the parameter to A's constructor needs to be computed inside of B's constructor, say by querying a database or something of that nature? Is there a way to use the setup below without providing A with a default constructor? Thanks in advance.
class A {
private:
int _i;
public:
A(int i) : _i(i) {}
};
A factoryA(bool b) {
if(b)
return A(1);
else return A(2);
}
class B {
private:
A _a;
public:
B(int j) {
if(j > 0)
_a = factoryA(true);
else _a = factoryA(false);
}
};
In this case it's better to use the pointer to A, i.e. A* _a, and then call A constructor wherever you want.
Member objects are always initialized before entry into the body (the part between the curly braces) of the constructor. If you don't mention a member in the initializer list, it gets default constructed. So mention it!
This calls the function
factoryA
with the argument valuetrue
ifj
is greater than 0 andfalse
otherwise, and initializes the member_a
with the value returned by that call.For classes[*], the
_a = factoryA(true);
line calls_a.operator=(factoryA(true))
. Calling a member function on_a
requires_a
to already be initialised. So if it weren't a compile-time error, it still wouldn't be valid.As long as
A
has a copy or move constructor, you can initialise it with a function return value, and that function can do anything you want, even using different constructors forA
depending on the arguments provided.[*] I know, there are exceptions.