在 C++ 中初始化之前声明一个对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/800368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Declaring an object before initializing it in c++
提问by Quantum7
Is it possible to declare a variable in c++ without instantiating it? I want to do something like this:
是否可以在 C++ 中声明一个变量而不实例化它?我想做这样的事情:
Animal a;
if( happyDay() )
a( "puppies" ); //constructor call
else
a( "toads" );
Basially, I just want to declare a outside of the conditional so it gets the right scope.
基本上,我只想在条件之外声明一个,以便它获得正确的范围。
Is there any way to do this without using pointers and allocating a
on the heap? Maybe something clever with references?
有没有办法在不使用指针和a
在堆上分配的情况下做到这一点?也许有一些聪明的参考?
采纳答案by Uri
You can't do this directly in C++ since the object is constructed when you define it with the default constructor.
您不能直接在 C++ 中执行此操作,因为该对象是在您使用默认构造函数定义它时构造的。
You could, however, run a parameterized constructor to begin with:
但是,您可以首先运行参数化构造函数:
Animal a(getAppropriateString());
Or you could actually use something like the ?: operator
to determine the correct string.
(Update: @Greg gave the syntax for this. See that answer)
或者您实际上可以使用类似的东西?: operator
来确定正确的字符串。(更新:@Greg 为此提供了语法。请参阅该答案)
回答by Greg Hewgill
You can't declare a variable without calling a constructor. However, in your example you could do the following:
您不能在不调用构造函数的情况下声明变量。但是,在您的示例中,您可以执行以下操作:
Animal a(happyDay() ? "puppies" : "toads");
回答by joce
You can't use references here, since as soon as you'd get out of the scope, the reference would point to a object that would be deleted.
你不能在这里使用引用,因为一旦你离开作用域,引用就会指向一个将被删除的对象。
Really, you have two choices here:
真的,你在这里有两个选择:
1- Go with pointers:
1-使用指针:
Animal* a;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
// ...
delete a;
2- Add an Init method to Animal
:
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" );
I'd personally go with option 2.
我个人会选择选项 2。
回答by Steve Fallows
I prefer Greg's answer, but you could also do this:
我更喜欢 Greg 的回答,但你也可以这样做:
char *AnimalType;
if( happyDay() )
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
I suggest this because I've worked places where the conditional operator was forbidden. (Sigh!) Also, this can be expanded beyond two alternatives very easily.
我建议这样做是因为我曾在禁止使用条件运算符的地方工作过。(叹气!)此外,这可以很容易地扩展到两种选择之外。
回答by paquetp
If you want to avoid garbage collection - you could use a smart pointer.
如果您想避免垃圾收集 - 您可以使用智能指针。
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.
If you still want to use the . syntax instead of ->, you can do this after the code above:
如果您仍然想使用 . 语法代替 ->,您可以在上面的代码之后执行此操作:
Animal& a = *p_a;
// do stuff with a. whatever
回答by Logan Capaldo
In addition to Greg Hewgill's answer, there are a few other options:
除了 Greg Hewgill 的回答之外,还有其他一些选择:
Lift out the main body of the code into a function:
将代码主体提升为一个函数:
void body(Animal & a) {
...
}
if( happyDay() ) {
Animal a("puppies");
body( a );
} else {
Animal a("toad");
body( a );
}
(Ab)Use placement new:
(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
回答by rkadeFR
The best work around is to use pointer.
最好的解决方法是使用指针。
Animal a*;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
回答by RodolfoAP
You can also use std::move:
您还可以使用 std::move:
class Ball {
private:
// This is initialized, but not as needed
sf::Sprite ball;
public:
Ball() {
texture.loadFromFile("ball.png");
// This is a local object, not the same as the class member.
sf::Sprite ball2(texture);
// move it
this->ball=std::move(ball2);
}
...
回答by DeadHead
Yes, you can do do the following:
是的,您可以执行以下操作:
Animal a;
if( happyDay() )
a = Animal( "puppies" );
else
a = Animal( "toads" );
That will call the constructors properly.
这将正确调用构造函数。
EDIT: Forgot one thing... When declaring a, you'll have to call a constructor still, whether it be a constructor that does nothing, or still initializes the values to whatever. This method therefore creates two objects, one at initialization and the one inside the if statement.
编辑:忘记了一件事......在声明 a 时,您仍然必须调用构造函数,无论它是一个什么都不做的构造函数,还是仍然将值初始化为任何值。因此,此方法创建两个对象,一个在初始化时,另一个在 if 语句中。
A better way would be to create an init() function of the class, such as:
更好的方法是创建类的 init() 函数,例如:
Animal a;
if( happyDay() )
a.init( "puppies" );
else
a.init( "toads" );
This way would be more efficient.
这种方式会更有效率。