2013-10-15 130 views
-2

我正在學習C++,最近我一直在閱讀和學習樹。我想知道,使用指針的優點是什麼?使用指針的優點/缺點

例如,如果我有一類節點,和我有一個調用的函數功能, 就是有

Function (Node *node) 
    Function (Node node) 

我知道一個需要一個指針作爲paremeter和另一個沒有之間的差異。但我完全不明白有什麼區別。

+0

這取決於Node'是如何定義',什麼功能是應該做的。 –

+5

大致相當於「在生活中,空氣與水的優勢是什麼?」 –

回答

1

Function (Node *node)可以在函數定義中修改node的內容。

With Function (Node node) you can not在函數定義中修改node的內容。

2
Function(Node node) 

使參數的副本。特別是,該函數永遠不會修改原始參數,所以如果您在函數中操作節點,那麼稱爲函數(節點)的代碼將不會看到這些更改。

有時候你想要這樣,以便其他人不能搞亂你的數據。

對於大型對象,複製數據所需的時間也是不使用指針的缺點。

+0

謝謝!我現在得到它:) – user2775084

+1

你應該upvote或接受答案,如果它幫助你。這就是這個網站的工作方式。 – forefinger

+0

你不僅應該積極響應,而且要接受答案 –

0

指針是變量,用於存儲另一個變量的位置

因此,Node * nodePointer的值將如下所示:x000000FF這是虛擬內存中的地址。如果你傳遞了這個地址,那麼這個函數可以修改那個地址的任何內容,在這種情況下你的節點對象。如果您傳遞對象本身,它將是該對象的副本,所以當方法返回時,原始對象將保持不變。

0

在一般而言:

Function (Node *node) 
Function (Node node) 
  • 第一允許一個 「空」 值傳遞(= 0nullptr
  • 第一可修改objecy
  • 第二要求Node有複製構造函數
  • 第二個效率較低,如果sizeof(Node)>sizeof(Node*)
0

首先,您必須瞭解對象是什麼。

House home; 

這個類「房子」的堆棧上的實例創建存儲,調用構造函數和指定名稱「家」來稱呼它隨後。

該對象現在佔用堆棧上的空間,但該堆棧只是指定用作堆棧的內存區域。與「中央車道」的命名方式相同,因爲它的建成時間是沿着城鎮的中心,今天它只是區分一條路與另一條路的一種方式。

當我們談論按價值傳遞時,

int SendGift(House h, Gift g) 

這意味着,當我們調用這個函數時,我們會創建一個新的本地副本,我們調用該函數來處理函數。

void SendGift(House h, Gift g) 
{ 
    h.porch.insert(g); 
    g.setLocation(h); 
} 

兩個「樓h」和「禮品G」是臨時功能SendGift的局部變量,因此,如果我們把它稱爲是這樣的:

House home; 
Gift gift(Gift::Dollars, 1 * 1000 * 1000); 
SendGift(home, gift); 

變量「家」是不變,禮物也是如此;我們所做的所有改變都是「g」和「h」,當功能結束時它們就會消失。

該代碼旨在說「做一百萬美元的禮物,並將其交付給比奇街123號的住所」。但是因爲我們是按價值傳遞的,所以它實際上說的是「捐一百萬美元的禮物,把房子和禮物複印一份,然後放入複製房,然後銷燬它們。」

它也可能非常昂貴,如果「House」對象爲幾個Kb大,那麼每次按值傳遞時,都需要將大量數據複製到臨時對象中。

對於小物體,如整數,這是No Big Deal(TM)。但是像大房子這樣的大物體,這太昂貴了。

所以不是我們可能想通過指針傳遞:

int SendGift(House* h, Gift* g) 
{ 
    h->porch.insert(g); 
    g->setLocation(h); 
} 

指針是變量包含地址,在一個對象的實例的存儲位置。因此,我們不是把這個房子,一磚一瓦地複製到SendGift的臨時文件中,而是通過了這個地址。所以,現在我們的呼叫

這樣,那麼,還有由指針(或引用)通過兩個主要的原因:當你想允許函數修改對象的內容,它被稱爲

  1. 與,
  2. 當您想通過避免創建輸入參數的副本來最小化調用該函數的成本。

通常當意圖是#2而不是#1時,您應該將該參數標記爲const。

#include <iostream> 

struct BigObj 
{ 
    BigObj() : m_useCount(0) {} 

    int m_useCount; 
    int m_stuff[4096]; 
}; 

void BigObjByValue(BigObj b) 
{ 
    b.m_useCount++; 
    std::cout << "BigObjByValue " << (&b) << ". m_useCount is now " << b.m_useCount << std::endl; 
} 

void BigObjByPtr(BigObj* b) 
{ 
    b->m_useCount++; 
    std::cout << "BigObjByValue " << (b) << ". m_useCount is now " << b->m_useCount << std::endl; 
} 

void BigObjByConstPtr(const BigObj* b) 
{ 
    //b->m_useCount++; // compiler won't allow this, try uncommenting. 
    std::cout << "BigObjByValue " << (b) << ". m_useCount is now " << b->m_useCount << std::endl; 
} 

int main() 
{ 
    BigObj mainB; 
    std::cout << "Created mainB at " << (&mainB) << " useCount = " << mainB.m_useCount << std::endl; 

    BigObjByValue(mainB); 
    std::cout << "in main, m_useCount = " << mainB.m_useCount << std::endl; 

    BigObjByPtr(&mainB); 
    std::cout << "in main, m_useCount = " << mainB.m_useCount << std::endl; 

    BigObjByConstPtr(&mainB); 
    std::cout << "in main, m_useCount = " << mainB.m_useCount << std::endl; 

    return 0; 
} 

ideone現場演示:http://ideone.com/SjkoNq