C++ 使用和不使用 new 运算符初始化对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8238968/
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
Initializing an object with and without new operator
提问by Aan
If I have a class Rectangle
如果我有一堂课 Rectangle
class Rectangle{
private:
double width;
double height;
public:
void Set(double w , double l){
width = w;
height = l;
}
};
and I decleare an object such:
我声明了一个对象,例如:
Rectangle *Obj;
and then try to initialize its properties:
然后尝试初始化其属性:
Obj->Set(3,5);
the compiler shows at run-time: The variable 'Obj' is being used without being initialized.
编译器在运行时显示: The variable 'Obj' is being used without being initialized.
The problem can be solved by:
问题可以通过以下方式解决:
Rectangle *Obj=new Rectangle;
I would ask about the reason! And why the compiler doesn't show any error at compiling time?
我想问一下原因!为什么编译器在编译时不显示任何错误?
回答by arne
Rectangle *Obj;
just defines a pointerto an object of class Rectangle
. Defining a pointer does not reserve any memory for the object itself, just for the pointer. Thus, if you access the pointer, you will likely end up at an address in memory that doesn't even belong to your process. However, the compiler cannot know that you haven't initialized the pointer (the keyword here is aliasing) and hence cannot output an error message.
只是定义了一个指向class 对象的指针Rectangle
。定义一个指针不会为对象本身保留任何内存,只为指针保留任何内存。因此,如果您访问该指针,您很可能会到达一个甚至不属于您的进程的内存地址。但是,编译器无法知道您尚未初始化指针(此处的关键字是别名),因此无法输出错误消息。
The solution is either using new
like you suggested, or declare an instance of Rectangle
like so:
解决方案要么new
像你建议的那样使用,要么Rectangle
像这样声明一个实例:
Rectangle Obj;
which will call a default constructor. You can then set your members using
这将调用默认构造函数。然后,您可以使用设置您的成员
Obj.Set(3, 5);
回答by Bj?rn Pollex
and I decleare an object such:
Rectangle *Obj;
我声明了一个对象,例如:
Rectangle *Obj;
Wrong, this declares a pointer, not an object. Pointers have to be initialized either using new
or by assigning them the address of an existing object.
错误,这声明了一个指针,而不是一个对象。必须使用new
或通过为它们分配现有对象的地址来初始化指针。
回答by sehe
Mmm a bit of confusion there:
嗯,有点混乱:
the compiler shows at run-time: The variable 'Obj' is being used without being initialized
编译器在运行时显示:正在使用变量“Obj”而未初始化
That is what you'd call compile time. Just straightening out the jargon.
这就是你所说的compile time。只是理顺行话。
Also, the simplest way would be to
此外,最简单的方法是
Rectangle Obj;
Obj.Set(3,5);
which is sufficient for most scenarios, except dynamic allocations, or polymorphic containers:
这对于大多数场景来说已经足够了,除了动态分配或多态容器:
std::vector<Shape*> v;
v.push_back(new Rectange());
v.back()->Set(3,5);
v.push_back(new Circle());
v.back()->Set(3,5);
//
Although whenever using new
you should be remembering to delete
as well. This can be quite a nightmare (in the light of exceptions, too). I suggest:
尽管无论何时使用,new
您都应该记住delete
。这可能是一场噩梦(也有例外)。我建议:
std::vector<std::shared_ptr<Shape*> > v;
v.push_back(std::make_shared<Rectange>());
v.back()->Set(3,5);
v.push_back(std::make_shared<Circle>());
v.back()->Set(3,5);
回答by Subhranshu
pointer without new is declaring something without memory .. SO u have to use new with pointer. However Rectangle rect; will defaultly allocate the memory .
没有 new 的指针声明了没有内存的东西.. 所以你必须使用 new 和指针。然而 Rectangle rect; 将默认分配内存。
to check this, make a constructor in Rectangle class like,
要检查这一点,请在 Rectangle 类中创建一个构造函数,例如,
void Rectangle
{
cout<<"Rectangle Constructor";
}
then,in main
然后,在主要
Rectangle *rect; -->>O/P -- "Nothing"
Rectangle rect2; -->>O/P -- Rectangle Constructor
rect=new Rectangle; -->>O/P -- Rectangle Constructor
回答by foxy
With Rectangle *Obj;
, you are declaring a pointer to a Rectangle, but you haven't told Obj
to which Rectangle it should point. You might set or instantiate Obj
later on to an existing Rectangle
or only if you require.
使用Rectangle *Obj;
,您声明了一个指向 Rectangle 的指针,但您没有告诉Obj
它应该指向哪个 Rectangle。您可以Obj
稍后设置或实例化现有的Rectangle
或仅在您需要时。
C++ is all about giving you precise control over your memory and performance. In fact, that's why it is used in some embedded environments! Automatically instantiating Obj
poses several "issues"
C++ 旨在让您精确控制内存和性能。事实上,这就是为什么在一些嵌入式环境中使用它的原因!自动实例化会Obj
带来几个“问题”
- When do we free
Obj
? - Who frees
Obj
? - What about the performance implications of creating a
Rectangle
on the heap? - Is this an environment in which we have enough resources (memory, CPU, etc) to even create the Rectangle, especially if it is large.
- Do you pass the address of
Obj
somewhere and then instantiate it at runtime through some complex method that we can't statically analyse?
- 我们什么时候有空
Obj
? - 谁释放
Obj
? Rectangle
在堆上创建 a 的性能影响如何?- 在这种环境中,我们是否有足够的资源(内存、CPU 等)来创建 Rectangle,尤其是当它很大时。
- 您是否传递
Obj
某个地方的地址,然后在运行时通过一些我们无法静态分析的复杂方法将其实例化?
What you do isn't a syntax error, which is what compilers throw errors on -- errors when compiling. An analyser (one is built into Visual Studio 2010 professional) might warn you that you're using an uninitialized variable, though that is optional and you may need to turn it on.
你所做的不是语法错误,这是编译器在编译时抛出错误的原因——错误。分析器(内置于 Visual Studio 2010 专业版中)可能会警告您正在使用未初始化的变量,尽管这是可选的,您可能需要将其打开。
回答by iammilind
why the compiler doesn't show any error at compiling time?
为什么编译器在编译时不显示任何错误?
Because, it's syntactically correct. However, such statements will lead to undefined behavior, smart compilers will always issue warning.
因为,它在语法上是正确的。但是,这样的语句会导致未定义的行为,智能编译器总是会发出警告。
In g++ you can turn such kind of compiler warning in errors.
在 g++ 中,您可以在错误中打开这种编译器警告。
回答by Dark Coder
The statement rectangle *obj
just means that there exist a pointer, that will point to the variable of type rectangle.
语句矩形*obj
只是意味着存在一个指针,它将指向矩形类型的变量。
With this statement you are just creating a pointer not the instance of the object rectangle for the usage of this pointer you must store the rectangle type variable's address in the pointer
使用此语句,您只是创建一个指针而不是对象矩形的实例,以便使用此指针,您必须将矩形类型变量的地址存储在指针中
The two ways of doing it are by
这样做的两种方法是
obj=new rectangle; //variable is created in the stack storage
or
或者
rectangle r;
obj =&r; //variable is created in the heap storage