使用和不使用 new 运算符初始化对象

发布于 2024-12-17 19:44:41 字数 501 浏览 1 评论 0原文

如果我有一个类 Rectangle

class Rectangle{

private:
    double width;
    double height;


public:
void    Set(double w , double l){
    width   = w;
    height  = l;
}
};

并且我声明了一个对象,例如:

Rectangle *Obj;

然后尝试初始化其属性:

Obj->Set(3,5);

编译器在运行时显示: 变量 'Obj' 正在使用但未初始化.

问题可以这样解决:

Rectangle *Obj=new Rectangle;

我就问一下原因!为什么编译器在编译时没有显示任何错误?

If I have a class 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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

倦话 2024-12-24 19:44:42
Rectangle *Obj;

只是定义了一个指向 Rectangle 类对象的指针。定义指针不会为对象本身保留任何内存,而只是为指针保留任何内存。因此,如果您访问该指针,您可能最终会到达内存中的一个地址,该地址甚至不属于您的进程。但是,编译器无法知道您尚未初始化指针(这里的关键字是别名),因此无法输出错误消息。

解决方案是像您建议的那样使用 new ,或者像这样声明 Rectangle 的实例:

Rectangle Obj;

它将调用默认构造函数。然后您可以使用设置您的成员

Obj.Set(3, 5);
Rectangle *Obj;

just defines a pointer to 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.

The solution is either using new like you suggested, or declare an instance of Rectangle like so:

Rectangle Obj;

which will call a default constructor. You can then set your members using

Obj.Set(3, 5);
旧城烟雨 2024-12-24 19:44:42

我声明了一个对象,例如:

矩形*Obj;

错误,这声明了一个指针,而不是一个对象。必须使用 new 或通过为它们分配现有对象的地址来初始化指针。

and I decleare an object such:

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.

只有一腔孤勇 2024-12-24 19:44:42

嗯,有点混乱:

编译器在运行时显示:变量“Obj”正在使用但未初始化

这就是您所说的编译时。只是理顺行话。

此外,最简单的方法是

Rectangle Obj;
Obj.Set(3,5);

除了动态分配或多态容器之外,对于大多数情况来说这已经足够了:

std::vector<Shape*> v;
v.push_back(new Rectange());
v.back()->Set(3,5);

v.push_back(new Circle());
v.back()->Set(3,5);

//

尽管每当使用new时,您应该记住删除 也是如此。这可能是一场噩梦(也有例外)。我建议:

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);

Mmm a bit of confusion there:

the compiler shows at run-time: The variable 'Obj' is being used without being initialized

That is what you'd call compile time. Just straightening out the jargon.

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:

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);
战皆罪 2024-12-24 19:44:42

使用 Rectangle *Obj;,您声明了一个指向 Rectangle 的指针,但您没有告诉 Obj 它应该指向哪个 Rectangle。您可以稍后将 Obj 设置或实例化到现有的 Rectangle,或者仅在需要时设置或实例化。

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

  • 我们什么时候释放 Obj
  • 谁释放了Obj
  • 在堆上创建矩形对性能有何影响?
  • 在这个环境中,我们是否有足够的资源(内存、CPU 等)来创建矩形,尤其是当矩形很大时。
  • 您是否将 Obj 的地址传递到某处,然后在运行时通过一些我们无法静态分析的复杂方法实例化它?

你所做的不是语法错误,这是编译器在编译时抛出错误的原因。分析器(内置于 Visual Studio 2010 professional 中)可能会警告您正在使用未初始化的变量,尽管这是可选的并且您可能需要将其打开。

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.

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"

  • 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?

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.

小矜持 2024-12-24 19:44:42

没有 new 的指针正在声明没有内存的东西..
所以你必须将 new 与指针一起使用。
然而
矩形 矩形;
会默认分配内存。

要检查这个,
在 Rectangle 类中创建一个构造函数,就像

void Rectangle
{
  cout<<"Rectangle Constructor";
}

然后在 main 中一样

Rectangle *rect; -->>O/P  -- "Nothing"
Rectangle rect2; -->>O/P  -- Rectangle Constructor
rect=new Rectangle; -->>O/P  -- Rectangle Constructor

pointer without new is declaring something without memory ..
SO u have to use new with pointer.
However
Rectangle rect;
will defaultly allocate the memory .

to check this,
make a constructor in Rectangle class like,

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
沧桑㈠ 2024-12-24 19:44:42

为什么编译器在编译时不显示任何错误?

因为,它语法正确。然而,这样的语句会导致未定义的行为,智能编译器总是会发出警告。

在 g++ 中,您可以将此类编译器警告转为错误。

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.

久随 2024-12-24 19:44:42

声明矩形 *obj 只是意味着存在一个指针,该指针将指向矩形类型的变量。

使用此语句,您只是创建一个指针
不是对象矩形的实例
要使用此指针,您必须将矩形类型变量的地址存储在指针中。

两种方法是通过

obj=new rectangle;  //variable is created in the stack storage

rectangle r;
obj =&r;     //variable is created in the heap storage

The statement rectangle *obj just means that there exist a pointer, that will point to the variable of type rectangle.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文