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(...); } }
Actually, yes, it is possible to bypass the constructor when you instantiate an object, if you use objenesis to instantiate the object for you. It does bytecode manipulations to achieve this. Deserializing an object will also bypass the constructor. It isn't possible to do this using reflection.
If we use the third constructor when we create the Dog object the breed and name fields are set to our desired values on one statement. If you omit a constructor, the Java compiler creates one for you internally. That default constructor has no parameters and no code so it really does nothing.
The constructors can be called explicitly or implicitly. The method of calling the constructor implicitly is also called the shorthand method. without any constructs (including default construct), objects cannot be created.
Java doesn't require a constructor when we create a class. However, it's important to know what happens under the hood when no constructors are explicitly defined. The compiler automatically provides a public no-argument constructor for any class without constructors. This is called the default constructor.
Store a pointer to an Object
rather than an actual Object
thus:
class Program { public: Object* myObject; // Will not try to call the constructor or do any initializing Program() { //Do initialization myObject = new Object(...); // Initialised now } }
Don't forget to delete
it in the destructor. Modern C++ helps you there, in that you could use an auto_ptr shared_ptr rather than a raw memory pointer.
Others have posted solutions using raw pointers, but a smart pointer would be a better idea:
class MyClass { std::unique_ptr<Object> pObj; // use boost::scoped_ptr for older compilers; std::unique_ptr is a C++0x feature public: MyClass() { // ... pObj.reset(new Object(...)); pObj->foo(); } // Don't need a destructor };
This avoids the need to add a destructor, and implicitly forbids copying (unless you write your own operator=
and MyClass(const MyClass &)
.
If you want to avoid a separate heap allocation, this can be done with boost's aligned_storage
and placement new. Untested:
template<typename T> class DelayedAlloc : boost::noncopyable { boost::aligned_storage<sizeof(T)> storage; bool valid; public: T &get() { assert(valid); return *(T *)storage.address(); } const T &get() const { assert(valid); return *(const T *)storage.address(); } DelayedAlloc() { valid = false; } // Note: Variadic templates require C++0x support template<typename Args...> void construct(Args&&... args) { assert(!valid); new(storage.address()) T(std::forward<Args>(args)...); valid = true; } void destruct() { assert(valid); valid = false; get().~T(); } ~DelayedAlloc() { if (valid) destruct(); } }; class MyClass { DelayedAlloc<Object> obj; public: MyClass() { // ... obj.construct(...); obj.get().foo(); } }
Or, if Object
is copyable (or movable), you can use boost::optional
:
class MyClass { boost::optional<Object> obj; public: MyClass() { // ... obj = Object(...); obj->foo(); } };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With