我知道我们可以使用堆对象执行以下操作:
/* Heap objects */
Pet *pet;
if (...)
pet = new Pet("Dog");
else
pet = new Pet("Cat");
但是如果我们想在堆栈上声明Pet
对象,我们该如何做?
/* Stack objects */
Pet pet;
if (...)
-?-
else
-?-
答案 0 :(得分:3)
尝试以下
Pet pet(theCondition ? "Dog" : "Cat");
或者,如果条件块比单个初始化存储更复杂,则const char*
用于初始化为单独的本地
const char* pArgument;
if (...) {
...
pArgument = "Dog";
} else {
...
pArgument = "Cat";
}
Pet pet(pArgument);
答案 1 :(得分:3)
string param;
if (...)
param = "Dog"
else
param = "Cat";
Pet pet(param);
答案 2 :(得分:1)
延迟初始化显然需要由基础对象本身完成。
if (...)
animal.Initialize("Dog");
else
animal.Initialize("Cat");
如果对象具有需要由派生类填充的虚拟方法,则不起作用 - 在这种情况下,指针是唯一可行的解决方案。
答案 3 :(得分:1)
如果您的类支持默认构造和复制分配,则以下方法可行:
Pet pet; //- assumes Pet class supports default construction.
if (theCondition)
{
pet = Pet("Dog"); //- assumes Pet class supports copy assignment.
}
else
{
pet = Pet("Cat");
}
当然,您需要支付两个结构和一份副本,以获得将您的宠物放入堆叠的特权。
答案 4 :(得分:1)
boost::optional可用于进行延迟初始化(即使对于容器):
boost::optional<Animal> d;
if(foo) d = Animal("Dog");
答案 5 :(得分: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;
}
答案 6 :(得分:0)
还有一个选择是使用函数,或者在C ++ 11中使用lambda:
auto returnArg = [&]() -> const char * {
if (...) return "Dog";
else return "Cat";
};
Animal animal(returnArg());
答案 7 :(得分:0)
将堆栈的加载分为两步。
void doTheThingToTheAnimal(Animal& animal) {
...
}
// select the animal
if (...) {
Animal animal("Dog");
doTheThingToTheAnimal(animal);
} else {
Animal animal("Cat");
doTheThingToTheAnimal(animal);
}