在C++初始化之前声明一个对象
是否有可能在不声明C++的情况下声明一个变量?我想要做这样的事情:在C++初始化之前声明一个对象
Animal a;
if(happyDay())
a("puppies"); //constructor call
else
a("toads");
Basially,我只想因此它的权利范围申报条件的外面。
有没有办法做到这一点,而不使用指针并在堆上分配a
?也许聪明的引用?
你不能这样直接在C,因为当你使用默认的构造函数定义它的对象构造做++。
你可以,但是,运行参数的构造函数来开始:
Animal a(getAppropriateString());
或者你实际上可以使用类似的?: operator
,以确定正确的字符串。 (更新:@Greg给出了这个语法,看到这个答案)
是的,你可以不执行以下操作:
Animal a;
if(happyDay())
a = Animal("puppies");
else
a = Animal("toads");
这将正确地调用构造函数。
编辑:忘了一件事... 当声明一个,你必须仍然调用一个构造函数,无论它是一个什么都不做的构造函数,或者仍然初始化值为任何东西。因此该方法创建两个对象,一个在初始化时,另一个在if语句内。
一种更好的方式是创建该类的一个init()函数,如:
Animal a;
if(happyDay())
a.init("puppies");
else
a.init("toads");
这样会更有效。
如果不调用构造函数,则不能声明变量。然而,在你的例子,你可以做到以下几点:
Animal a(happyDay() ? "puppies" : "toads");
你不能在这里使用引用,因为只要你离开范围,引用就会指向一个对象,被删除。
真的,你有两个选择:
1的指针转到:
Animal* a;
if(happyDay())
a = new Animal("puppies"); //constructor call
else
a = new Animal("toads");
// ...
delete a;
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");
我会亲自去与选项2.
我更喜欢格雷格的答案,但你也可以这样做:
char *AnimalType;
if(happyDay())
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
我建议这样做是因为我曾经在那些条件运算符被禁止的地方工作。 (叹气!)另外,这可以很容易地扩展到两种选择之外。
除了格雷格Hewgill的回答,还有一些其他选项:
提升了代码的主体为一个功能:
void body(Animal & a) {
...
}
if(happyDay()) {
Animal a("puppies");
body(a);
} else {
Animal a("toad");
body(a);
}
(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
如果你想避免垃圾收集 - 你可以使用智能指针。
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.
如果你仍然想使用。语法代替 - >,你可以在上面的代码之后执行此操作:
Animal& a = *p_a;
// do stuff with a. whatever
最好的解决方法是使用指针。
Animal a*;
if(happyDay())
a = new Animal("puppies"); //constructor call
else
a = new Animal("toads");
看到RAII(资源采集是初始化) – newacct 2009-04-29 00:57:03
,如果它是一个非静态全局/命名空间范围,那么它是值得大家注意的,你可以不初始化它实际上宣告:EXTERN动物; ...动物(东西); – 2009-04-29 14:25:58
@newacct:一个链接将有助于https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii – spinkus 2014-06-10 22:08:24