2011-11-23 59 views
16

如果我有一个类Rectangle初始化对象有和没有新的运营商

class Rectangle{ 

private: 
    double width; 
    double height; 


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

我decleare对象,例如:

Rectangle *Obj; 

,然后尝试初始化它的属性:

Obj->Set(3,5); 

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

的问题可以通过解决:

Rectangle *Obj=new Rectangle; 

我想请教一下原因!为什么编译器在编译时不显示任何错误?

回答

20
Rectangle *Obj; 

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

解决方法是,使用new喜欢你的建议或声明的Rectangle一个实例,像这样:

Rectangle Obj; 

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

Obj.Set(3, 5); 
+7

只是一个nit,但是'Rectangle * Obj;'不只是_declare_;它也是_defines_。它确实保留了内存;足够的内存来存储指针。 –

+0

@JamesKanze:你当然是对的。我会马上更新我的回答 – arne

7

和我decleare物体例如:

Rectangle *Obj; 

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

+3

指针是++对象,至少用C。这定义了一个类型为“Rectangle *”的对象。当然,未初始化。 –

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

不是最简单的(也是最好的)方式:'Rectangle Obj = {3,5};'。作为一般规则,您不应该创建未初始化的对象。 (关于唯一的例外可能是,如果你正在阅读它,在下一个语句中使用'>>')。 –

+1

@JamesKanze:'Rectangle Obj'不会产生未初始化的对象(至少我不假设它是一个没有默认构造函数且没有字段初始值设定项的结构,并且我倾向于不在初学者答案中抛出C++ 11细节; shared_ptr可以从boost使用,不能使用统一初始化(** PS **'width'和'height'都是私有的) – sehe

+2

它实现了'Rectangle',我错过了'private';没有办法创建一个初始化的'Rectangle',他需要一个构造函数,而不是'Set'函数。 –

2

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

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

在g ++中,你可以打开这样的错误编译器警告。

3

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

C++是关于给你精确控制你的内存和性能。事实上,这就是为什么它在某些嵌入式环境中使用的原因!自动实例化Obj摆出几个“问题”

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

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

3

指针没有新的声明是没有记忆的东西设置你的会员.. SO u必须使用新的具有指针。 但是 矩形矩形; 将默认分配内存。

检查此, 使Rectangle类像一个构造函数,

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

然后,在主

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

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

这种说法你是刚创建的指针 不是对象矩形 的这个指针,你必须存储的矩形类型变量的地址指针

做的两种方式是使用实例通过

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

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

我认为这是相反的。一个是新建的,一个是堆,另一个是堆栈。 – Aan