2011-11-23 63 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