Reputation: 656
Current structure is something like
class B {
//no default constructor
//this is a class in a third-party library, can't be modified
B(Lots ofData, AndOther arguments);
}
class A {
B b;
A(some_parameters){
//Do a lot of stuff with those parameters, make Results
B b(Results, Results); //ERROR
}
}
So, I need to call the constructor on B
, but I don't have the information early enough to do it in the initializer list. How do I call the constructor on B
later? Because B
doesn't have a trivial constructor, I can't exactly initialize with some dumb defaults and overwrite it later, either.
I can't change the B
class.
Upvotes: 1
Views: 63
Reputation: 217135
Another alternative in C++11 is delegating constructor, something similar to:
Result foo(Parameters some_parameters)
{
//Do a lot of stuff with those parameters, make Results
}
class A
{
B b;
public:
A(Parameters some_parameters) : A(foo(some_parameters)){}
private:
A(Result result) : b(Results, Results) {}
};
Upvotes: 2
Reputation: 15943
If B
has a copy/move constructor, you could simply make a function that returns you a B
and use that to initialize the member like so:
B makeB(some_parameters) {
//Do a lot of stuff with those parameters, make Results
return B(Results, Results);
}
class A {
B b;
A(some_parameters)
: b(makeB(some_parameters))
{
}
};
If copying/moving a B
into your member is not an option, then one simple solution would be to just allocate the B
object dynamically. That way you could move all the "lots of stuff, make Results" into a function
#include <memory>
std::unique_ptr<B> makeB(some_parameters) {
//Do a lot of stuff with those parameters, make Results
return std::make_unique<B>(Results, Results);
}
class A {
std::unique_ptr<B> b;
A(some_parameters)
: b(makeB(some_parameters))
{
}
};
If you want your B
to live directly inside the A
object, you could use an std::optional<B>
or an unnamed union in which you emplace the object at a later point:
#include <memory>
class A {
union {
B b;
};
A(some_parameters) {
//Do a lot of stuff with those parameters, make Results
new (&b) B(Results, Results);
}
~A() { // this is only needed if B has a non-trivial destructor
b.~B();
}
};
Upvotes: 3