2010-01-05 51 views
2

因爲我已經從c#到C++,所有在C++中看起來都很瘋狂。 我只是想知道,如果有人能解釋我爲什麼我們這些種在C++中實例化的: 方法1:不同類型的在C++上實例化

ClassA obj1; // this is going to stack 

方法2:

ClassA *obj1 = new ClassA(); //this is going to heap 

,而我們沒有共同的實例化在C C#的方式++:

ClassA obj2 = new obj2(); 

和方法1一個問題我從ClassA的,但沒有()得到一個實例,這是確切地說,我感到困惑,爲什麼我們不得不這樣安心? 我們的ClassA有一個構造函數,但實例化沒有括號? 我們怎麼稱其構造函數?

P.S:我讀過這些主題:

Different methods for instantiating an object in C++

Stack, Static, and Heap in C++

What and where are the stack and heap?

+0

C#沒有兩種實例化方式,因爲運行時爲您管理內存。 – 2013-12-08 11:03:48

+0

在方法1中,obj是對ClassA對象的引用。在方法2中,obj是一個指向ClassA對象的指針。 C++中的new返回一個指向分配內存的指針。你必須告訴新建什麼類型的對象。這就是爲什麼第三個選項不起作用的部分原因。 obj2還沒有被定義爲一個對象。在代碼中的這一點上,它只是將被用作引用創建對象的標識符的文本。 – iheanyi 2014-05-16 16:45:20

回答

3

事實上移動來自Java或C#語言的C++可能令人望而生畏,我也經歷了它。

第一個也是最重要的區別是,在C++中你幾乎總是管理你自己的內存。在堆上創建對象時,您有責任刪除它,以免它泄漏內存 - 這意味着您可以在看到合適的時候刪除它。在堆棧中創建對象時,它會在超出範圍時自動刪除 - 在超出範圍之後,請注意不要使用它。

實施例:

void do_queue(B& queue) 
{ 
    Evt *e = new Evt; 
    queue.queueEvent(e); 
} // all well, e can be popped and used (also must be deleted by someone else!) 

void do_queue(B& queue) 
{ 
    Evt e; 
    queue.queueEvent(&e); 
} // e is out of scope here, popping it from the queue and using it will most likely cause a sigseg 

這就是說,這兩種方法,可以在一個方面顯著不同:第一個創建一個對象。第二個創建一個指向對象的指針。有關指針的好處是你可以將它們作爲參數傳遞給它們,只有最小的內存被複制到堆棧上(指針被複制,而不是整個對象)。當然,你總是可以通過使用「&」獲取分配給堆棧的對象的地址,或者將其作爲參考傳遞給它 - 但是,當使用堆棧中分配的對象時,你尤其要小心它們的範圍。

我發現這個網站一個很好的資源,當我從Java移動到C++:http://www.parashift.com/c++-faq-lite/ - 你可能會發現它太,它提供了很多很好的解釋

1

C++的語法就是如此。如果您想使用默認的構造函數,你只需要調用它像:

ClassA obj1; 

如果你想有一個參數的構造函數,你會這樣稱呼它:

ClassA obj1(5); 
2

在C++中,你必須決定你在哪裏希望你的對象居住。我的意思是在哪裏,內存,堆棧或堆。

實例化一個對象是一個兩步過程。首先你需要內存,然後把它放在堆棧上,或者從堆中分配它。其次,你用你想要的值初始化內存,即通過調用它的構造函數來構造對象。

這兩種語法適用於這兩種可能的不同內存位置:堆棧和堆。

關於堆棧分配對象的語法和明顯缺失的括號,它是在對象的定義和構造與函數的聲明之間消除歧義。的確,ClassA obj();聲明瞭一個不帶參數的函數,並返回一個ClassA對象。