Ленивая инициализация для стековых объектов? - PullRequest
2 голосов
/ 25 января 2012

Я знаю, что мы можем сделать следующее с кучей объектов:

/* Heap objects */
Pet *pet;

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

Но как нам это сделать, если мы хотим, чтобы объект Pet был объявлен в стеке?

/* Stack objects */
Pet pet;

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

Ответы [ 8 ]

3 голосов
/ 25 января 2012
string param;
if (...)
   param = "Dog"
else 
   param = "Cat";

Pet pet(param);
3 голосов
/ 25 января 2012

Попробуйте следующее

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

Или, если условные блоки сложнее, чем одно хранилище инициализации, то const char*, который используется для инициализации в качестве отдельной локальной

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

Pet pet(pArgument);
1 голос
/ 25 января 2012

boost :: необязательный может использоваться для отложенной инициализации (даже для контейнеров):

boost::optional<Animal> d;
if(foo) d = Animal("Dog"); 
1 голос
/ 25 января 2012

Если ваш класс поддерживает конструкцию по умолчанию и назначение копирования, будет работать следующее:

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

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

Конечно, вам придется заплатить за две конструкции и копию за привилегию положить вашего питомца в стек.

1 голос
/ 25 января 2012

Ленивая инициализация, очевидно, должна выполняться самим базовым объектом.

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

Это не работает, если у объекта есть виртуальные методы, которые должны быть заполнены производными классами - в этом случаеуказатель - единственное работоспособное решение.

0 голосов
/ 25 января 2012

Разбить загрузку стека на 2 шага.

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


// select the animal
if (...) {
  Animal animal("Dog");
  doTheThingToTheAnimal(animal);
} else {
  Animal animal("Cat");
  doTheThingToTheAnimal(animal); 
}
0 голосов
/ 25 января 2012

Еще один вариант - использовать функции, или в C ++ 11 лямбда-выражения:

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

Animal animal(returnArg());
0 голосов
/ 25 января 2012

Я думаю, вы не можете иметь то же самое с объектами стека.

Однако есть несколько альтернатив:

/* Stack objects */

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

или не очень ленивый

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

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