In C++, I want to define an object as a member of a class like this:
Object myObject;
However doing this will try to call it's parameterless constructor, which doesn't exist. However I need the constructor to be called after the containing class has done some initialising. Something like this.
class Program
{
public:
Object myObject; //Should not try to call the constructor or do any initializing
Program()
{
...
//Now call the constructor
myObject = Object(...);
}
}
You can use a pointer (or a smart pointer) to do that. If you do not use a smart pointer, do make sure that your code free memory when the object is deleted. If you use a smart pointer, do not worry about it.
You may also be able to rewrite your code to use the constructor initializer list, if you can move off the other initialization into constructors:
You need to be aware that following such a pattern will lead you to a path where you do a lot of work in constructors, which in turn leads to needing to grasp exception handling and safety (as the canonical way to return an error from a constructor is to throw an exception).
You can fully control the object construction and destruction by this trick:
Apply on your sample:
Big advantage of this solution, is that it does not require any additional allocations, and object memory allocated as normal, but you have control when call to constructor.
Another sample link
Store a pointer to an
Object
rather than an actualObject
thus:
Don't forget to
delete
it in the destructor. Modern C++ helps you there, in that you could use anauto_ptrshared_ptr rather than a raw memory pointer.Others have posted solutions using raw pointers, but a smart pointer would be a better idea:
This avoids the need to add a destructor, and implicitly forbids copying (unless you write your own
operator=
andMyClass(const MyClass &)
.If you want to avoid a separate heap allocation, this can be done with boost's
aligned_storage
and placement new. Untested:Or, if
Object
is copyable (or movable), you can useboost::optional
:If you have access to boost, there is a handy object that is provided called
boost::optional<>
- this avoids the need for dynamic allocation, e.g.