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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:14:31  来源:igfitidea点击:

Initializing an object with and without new operator

c++memory-managementnew-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 newlike you suggested, or declare an instance of Rectanglelike 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 newor 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 newyou should be remembering to deleteas 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 Objto which Rectangle it should point. You might set or instantiate Objlater on to an existing Rectangleor 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 Objposes several "issues"

C++ 旨在让您精确控制内存和性能。事实上,这就是为什么在一些嵌入式环境中使用它的原因!自动实例化会Obj带来几个“问题”

  • When do we free Obj?
  • Who frees Obj?
  • What about the performance implications of creating a Rectangleon 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 Objsomewhere 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 *objjust 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