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

时间:2011-11-23 08:14:12

标签: c++ memory-management new-operator

如果我有课程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);

编译器在运行时显示:The variable 'Obj' is being used without being initialized.

问题可以通过以下方式解决:

Rectangle *Obj=new Rectangle;

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

7 个答案:

答案 0 :(得分:24)

Rectangle *Obj;

只为类Rectangle的对象定义指针。定义指针不会为对象本身保留任何内存,仅用于指针。因此,如果您访问指针,您可能最终会在内存中甚至不属于您的进程的地址。但是,编译器无法知道您没有初始化指针(此处的关键字是别名),因此无法输出错误消息。

解决方案是使用您建议的new,或者声明Rectangle的实例,如下所示:

Rectangle Obj;

将调用默认构造函数。然后,您可以使用

设置您的成员
Obj.Set(3, 5);

答案 1 :(得分:8)

  

我发现了一个对象:

Rectangle *Obj;

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

答案 2 :(得分:4)

那边有点混乱:

  

编译器在运行时显示:变量'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 时,您也应该记住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);

答案 3 :(得分:3)

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

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

  • 我们何时免费Obj
  • 谁解放了Obj
  • 在堆上创建Rectangle的性能影响如何?
  • 这是一个环境,我们有足够的资源(内存,CPU等)甚至可以创建Rectangle,特别是如果它很大。
  • 你是否在某处传递了Obj的地址,然后通过一些我们无法静态分析的复杂方法在运行时实例化它?

你所做的不是语法错误,这是编译器抛出错误的原因 - 编译时的错误。分析器(一个内置于Visual Studio 2010专业版中)可能会警告您使用的是未初始化的变量,尽管这是可选的,您可能需要打开它。

答案 4 :(得分:3)

没有new的指针声明没有内存的东西.. 所以你必须使用new with pointer。 然而 矩形矩形; 将默认分配内存。

检查一下, 在Rectangle类中创建一个构造函数,如

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

然后,在主

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

答案 5 :(得分:2)

  

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

因为,语法正确。但是,此类陈述将导致未定义的行为,智能编译器将始终发出警告。

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

答案 6 :(得分:-1)

语句矩形*obj只表示存在一个指针,指向矩形类型的变量。

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

这两种方式是通过

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

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