2012-01-24 3 views
2

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

/* Heap objects */ 
Pet *pet; 

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

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

/* Stack objects */ 
Pet pet; 

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

ответ

3

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

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

Или, если условные блоки являются более сложными, чем один инициализацией МАГАЗИНА const char*, который используется для инициализации в качестве отдельного локального

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

Pet pet(pArgument); 
+0

Но если это является более сложным, если-другое заявление? –

+0

@LeifEricson просто добавила более сложную версию за секунду назад – JaredPar

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

Pet pet(param); 
1

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

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

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

0

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

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

/* Stack objects */ 

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

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

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

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

Ваше первое решение не очень хорошо, потому что эти объекты не будут существовать вне if-else. –

+0

Хорошо, но вы этого не спрашивали. – frast

1

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

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

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

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

0

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

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

Animal animal(returnArg()); 
0

Перерыв загрузка стека в 2 этапа.

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


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

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

boost::optional<Animal> d; 
if(foo) d = Animal("Dog"); 
Смежные вопросы