Qua*_*um7 47 c++ scope declaration instantiation
是否可以在不实例化的情况下在c ++中声明变量?我想做这样的事情:
Animal a;
if( happyDay() )
a( "puppies" ); //constructor call
else
a( "toads" );
Run Code Online (Sandbox Code Playgroud)
基本上,我只是想声明条件的外部,以便它获得正确的范围.
有没有办法在不使用指针和a在堆上分配的情况下执行此操作?也许引用聪明的东西?
Gre*_*ill 41
如果不调用构造函数,则无法声明变量.但是,在您的示例中,您可以执行以下操作:
Animal a(happyDay() ? "puppies" : "toads");
Run Code Online (Sandbox Code Playgroud)
Uri*_*Uri 34
您不能直接在C++中执行此操作,因为在使用默认构造函数定义对象时会构造该对象.
但是,您可以运行参数化构造函数以开头:
Animal a(getAppropriateString());
Run Code Online (Sandbox Code Playgroud)
或者您实际上可以使用类似的东西?: operator来确定正确的字符串.(更新:@Greg给出了这个的语法.看到那个答案)
joc*_*oce 22
你不能在这里使用引用,因为只要你离开作用域,引用就会指向一个将被删除的对象.
真的,你有两个选择:
1-使用指针:
Animal* a;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
// ...
delete a;
Run Code Online (Sandbox Code Playgroud)
2-添加Init方法Animal:
class Animal
{
public:
Animal(){}
void Init( const std::string& type )
{
m_type = type;
}
private:
std:string m_type;
};
Animal a;
if( happyDay() )
a.Init( "puppies" );
else
a.Init( "toads" );
Run Code Online (Sandbox Code Playgroud)
我个人选择2.
Ste*_*ows 16
我更喜欢Greg的回答,但你也可以这样做:
char *AnimalType;
if( happyDay() )
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
Run Code Online (Sandbox Code Playgroud)
我建议这是因为我曾经禁止使用条件运算符的地方.(叹气!)此外,这可以非常容易地扩展到两个替代方案之外.
从 c++17 开始,现在有一种无开销的方法可以做到这一点:std::optional。本例中的代码为:
#include <optional>
std::optional<Animal> a;
if (happyDay()) {
a.emplace("puppies");
} else {
a.emplace("toads");
}
Run Code Online (Sandbox Code Playgroud)
如果你想避免垃圾收集 - 你可以使用智能指针.
auto_ptr<Animal> p_a;
if ( happyDay() )
p_a.reset(new Animal( "puppies" ) );
else
p_a.reset(new Animal( "toads" ) );
// do stuff with p_a-> whatever. When p_a goes out of scope, it's deleted.
Run Code Online (Sandbox Code Playgroud)
如果你还想使用.语法而不是 - >,您可以在上面的代码之后执行此操作:
Animal& a = *p_a;
// do stuff with a. whatever
Run Code Online (Sandbox Code Playgroud)
除了Greg Hewgill的回答,还有其他一些选择:
将代码的主体提升为一个函数:
void body(Animal & a) {
...
}
if( happyDay() ) {
Animal a("puppies");
body( a );
} else {
Animal a("toad");
body( a );
}
Run Code Online (Sandbox Code Playgroud)
(Ab)使用新的位置:
struct AnimalDtor {
void *m_a;
AnimalDtor(void *a) : m_a(a) {}
~AnimalDtor() { static_cast<Animal*>(m_a)->~Animal(); }
};
char animal_buf[sizeof(Animal)]; // still stack allocated
if( happyDay() )
new (animal_buf) Animal("puppies");
else
new (animal_buf) Animal("toad");
AnimalDtor dtor(animal_buf); // make sure the dtor still gets called
Animal & a(*static_cast<Animal*>(static_cast<void*>(animal_buf));
... // carry on
Run Code Online (Sandbox Code Playgroud)