0

I need a MyClass object for the entire lifetime of main(), but only if some flag useMyObject is true.

  • I believe that the declaration MyClass myObject runs the constructor. Is that true? I couldn't manage to look it up.
  • If it is, how can I avoid calling the constructor twice?

The constructor grabs a resource that I only want to grab once and only if the flag is set. This is my code:

int main() { MyClass myObject; // ... if ( useMyObject ) { myObject = MyClass(42); } // ... } 
10
  • 3
    Declare the object inside of the scope of the if. Otherwise, how do you intend to use a non-constructed object? Commented Sep 12, 2013 at 8:13
  • @juanchopanza The object will be used later, so it can't die when the scope of if ends. For example I could have another if ( useMyObject ) later. Commented Sep 12, 2013 at 8:14
  • You could declare a pointer instead and leave it null if you don't need it. Commented Sep 12, 2013 at 8:14
  • @RogerRowland Would that be with MyClass *myObject ... myObject = new MyClass(42)? Commented Sep 12, 2013 at 8:15
  • But how can it be used later, if it isn't constructed properly? Commented Sep 12, 2013 at 8:16

3 Answers 3

6

An easy way to do is to use std::unique_ptr:

std::unique_ptr<MyClass> myObjectPtr; if(useMyObject) myObjectPtr.reset(new MyClass(42)); if(myObjectPtr) myObjectPtr->method(); 

But note that it will require a heap allocation, which may be actually more expensive than an "empty" construction. To avoid the cost of heap allocation you can use boost::optional which is used similarly to a pointer, but in fact the storage for the object is allocated on the stack:

boost::optional<MyClass> myObject; if(useMyObject) myObject = MyClass(42); if(myObject) myObject->method(); 

As you see in any of the above cases, the code will be littered with conditions.

If you are allowed to change the MyClass I would suggest to just construct an "empty" object using the non-parametric constructor. You only need to construct the object into a state where it actually does nothing, but it should not crash the application if used. That empty construction should be cheap and it is only a one time cost anyway.

It would be even better if you can move the object into a scope where it is actually used and avoid the uninitialized/empty object altogether:

if(useMyObject) { MyClass myObject(42); // use the object here and nowhere else. } 
Sign up to request clarification or add additional context in comments.

6 Comments

Cool - but I hate all these ifs, I wonder what the problem really is.
If you hate the ifs, use &&: myObject && myObject->method(); :P
@doctorlove There's just one if, and in there, the object is passed to another class (not developed by me) that uses that object periodically. For some reason, going out of scope after the if would destroy the object.
@jrok nice. even more fun if you do it with if-else logic encoded with trigraphs and a ternary operator =P Keeps your co-workers on their toes.
There will be ifs everywhere the object is used. This is just a work-around for a flawed design.
|
2

Yes the constructor will be run when you declare the object.
You could use a std::unique_ptr instead and just initialise the object if required.
However, that will probably leave your code littered with ifs, so there might be a better way to arrange the code.

Comments

0
MyClass& getMyObject() static MyClass myObject(42); return myObject; } 

Can even be called if you don't actually need the object but just want to ensure that it exists:

int main() { // ... if ( createMyObjectNow ) { getMyObject(); } // ... } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.