2015-01-26 44 views
2

所以我從Java到來,現在正在學習C++返回一個指針變量,爲什麼在堆,而不是變量本身在C++

我瞭解指針工作,什麼棧和堆內存是和我GOOGLE了很多,但我似乎無法理解爲什麼我們不會只是返回對象本身,而不是像這個例子中的指針指向堆上創建的對象:

(我明白我們爲什麼有在第一個例子中分配堆上的對象而不是堆上的對象)。

class Thingy; 

Thingy* foo() 
{ 
    Thingy *pointerToHeap = new Thingy(); 
    return pointerToHeap; 
} 

所以從Java的未來我會做這樣的:

class Thingy; 

Thingy foo() 
{ 
    Thingy a; 
    return a; 
} 

正如我幾乎總是上了堆中對象的壽命比在堆棧上的對象不再是原因,我不明白爲什麼我們會寫函數就像第一個例子,如果我的函數也可以。

+0

如果變量是太大,不適合在堆棧上你沒有選擇(例如當你需要一大堆東西時) – Borgleader 2015-01-26 18:51:24

+0

返回值是合法的,但並不總是可取的。 – 2015-01-26 18:51:55

+0

那麼,什麼樣的編程練習會更好?何時才能返回值呢? – 2015-01-26 18:55:21

回答

6

你的兩個例子是不等同

在Java例子,你忘了真正創建一個對象。
更正代碼:

class Thingy; 

Thingy foo() { 
    Thingy a = new Thingy(); 
    return a; 
} 

語法爪哇指針和C++指針是不同的,因爲Java不允許堆棧分配,只堆分配,並且沒有非類類型的分配。這意味着不需要區分單級指針,多級指針和非指針變量,因爲它們都是單級指針。

有他們之間的附加語義差別:
雖然C++ 確實支持垃圾回收,這是極爲罕見的,而在Java中它是強制性的。

因此,在C++中,有兩個更好的選擇:

  1. 返回按值,如果複製或移動是便宜:

    class Thingy; 
    Thingy foo() { 
        Thingy t; // Thingy t(); would declare a function instead. 
        return t; // The copy/move will probably be elided due to NRVO 
    } 
    
  2. 使用std::unique_ptr返回,以明確地表示轉讓所有權並使其異常安全:

    #include <memory> 
    class Thingy; 
    std::unique_ptr<Thingy> foo() { 
        unique_ptr<Thingy> p = new Thingy(); 
        return p; 
    } 
    

    此選項如果從您的版本更改,也可以在幾乎所有的平臺上都可以打破ABI。
    它雖然破壞了API,但很容易糾正。

    • 一個替代方案是返回一個std::shared_ptr,以允許使用make_shared

      #include <memory> 
      class Thingy; 
      std::shared_ptr<Thingy> foo() { 
          auto p = std::make_shared<Thingy>(); 
          return p; 
      } 
      
+0

'Thingy t();'這裏不是最令人頭疼的解析嗎? – 2015-01-26 19:15:20

+0

@NeilKirk:差不多。不過,已經糾正了。 – Deduplicator 2015-01-26 19:16:00

+0

我試過不寫這個: 'Thingy a = new Thingy();' 因爲那隻會在堆上再創建一個對象,不是嗎? – 2015-01-26 19:22:01

2

該指針示例返回一個指向該對象的指針。它被分配在堆上,調用者可以直接訪問相同的副本。調用者還負責在某個時刻從堆中刪除Thingy。

對象實例示例在堆棧上構造一個Thingy,然後將其複製到調用者的Thingy中,假設您有一行Thingy2 = Thingy1.foo()調用該函數。與使用一個對象相比,取決於對象的大小,會有性能損失。

使用std :: shared_ptr可能會更像您習慣的Java。它會創建對象的一個​​副本,並在不再引用它時處理它。你可以傳遞它,每一個引用都是對象的同一個副本。

相關問題