Ori Popowski
Ori Popowski

Reputation: 10662

Lazy initialization for stack objects?

I know we can do the following with heap objects:

/* Heap objects */
Pet *pet;

if (...)
    pet = new Pet("Dog");
else
    pet = new Pet("Cat");    

But how do we do it if we wanted the Pet object to be declared on the stack?

/* Stack objects */
Pet pet;

if (...)
    -?-
else
    -?-

Upvotes: 2

Views: 252

Answers (8)

pmr
pmr

Reputation: 59811

boost::optional can be used to get lazy initialization (even for containers):

boost::optional<Animal> d;
if(foo) d = Animal("Dog"); 

Upvotes: 1

JPedius
JPedius

Reputation: 1

Break the loading of the stack into 2 steps.

void doTheThingToTheAnimal(Animal& animal) {
  ...
}


// select the animal
if (...) {
  Animal animal("Dog");
  doTheThingToTheAnimal(animal);
} else {
  Animal animal("Cat");
  doTheThingToTheAnimal(animal); 
}

Upvotes: 0

JaredPar
JaredPar

Reputation: 754715

Try the following

Pet pet(theCondition ? "Dog" : "Cat");

Or if the conditional blocks are more complex than a single initialization store the const char* which is used for initialization as a separate local

const char* pArgument;
if (...) {
  ...
  pArgument = "Dog";
} else {
  ...
  pArgument = "Cat";
}

Pet pet(pArgument);

Upvotes: 3

Benjamin Lindley
Benjamin Lindley

Reputation: 103693

One more option is to use functions, or in C++11, lambdas:

auto returnArg = [&]() -> const char * {
    if (...) return "Dog";
    else return "Cat";
};

Animal animal(returnArg());

Upvotes: 0

Brian Lenoski
Brian Lenoski

Reputation: 117

If your class supports default construction and copy assignment, the following would work:

Pet pet;  //- assumes Pet class supports default construction.

if (theCondition)
{
    pet = Pet("Dog");  //- assumes Pet class supports copy assignment.
}
else
{
    pet = Pet("Cat");
}

Of course, you'll have to pay for two constructions and a copy for the privilege of putting your pet on the stack.

Upvotes: 1

frast
frast

Reputation: 2740

I think you cant have the same with stack objects.

However, here are some alternatives:

/* Stack objects */

if (...)
{
  Animal animal("Cat");
  ...
}
else
{
  Animal animal("Dog");
  ...
}

or not so lazy

Animal cat("Cat");
Animal dog("Dog");
Animal *animal;

if (...)
{
  animal = &cat;
}
else
{
  animal = &dog;
}

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308158

The lazy initialization obviously needs to be done by the base object itself.

if (...)
    animal.Initialize("Dog");
else
    animal.Initialize("Cat");

This doesn't work if the object has virtual methods that need to be filled in by derived classes - in that case the pointer is the only workable solution.

Upvotes: 1

Armen Tsirunyan
Armen Tsirunyan

Reputation: 132994

string param;
if (...)
   param = "Dog"
else 
   param = "Cat";

Pet pet(param);

Upvotes: 3

Related Questions