堆栈对象的延迟初始化?

时间:2012-01-24 22:04:19

标签: c++ stack declaration

我知道我们可以使用堆对象执行以下操作:

/* Heap objects */
Pet *pet;

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

但是如果我们想在堆栈上声明Pet对象,我们该如何做?

/* Stack objects */
Pet pet;

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

8 个答案:

答案 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); 
}