2015-04-20 43 views
0

我有一個Node類和一個NodeManager類。 NodeManager對象持有指向節點的指針。我想讓這個Node指針指向一個在堆上分配的Node對象。堆分配發生在NodeManager.init()指針數據成員在堆上初始化

這是代碼。

class Node 
{ 
public: 
    int index; 
}; 

class NodeManager 
{ 
public: 
    NodeManager() {} 
    void initNode(Node *b) 
    { 
     b = new Node(); 
    } 

    Node *node; 
}; 

int main() 
{ 
    NodeManager manager; 
    manager.initNode(manager.node); 

    cout << manager.node << endl; //prints a bad pointer 

    system("pause"); 
    return 0; 
} 

當然,當我改變initNode()到:

void initNode() 
{ 
    this->node = new Node(); 
} 

manager對象實際上 「記住」 它node的地址。 問題是,在第一個代碼中,地址不被記住,應用程序輸出一個錯誤的地址。這是爲什麼?

編輯: 爲了使事情更清楚,我正在處理一個具有數據成員的類,該成員是指向對象的指針。我的類有一個遞歸成員函數,它將數據成員指針作爲「起點」參數,並一直調用自己分配和創建對象的「子」。但是,然後,我得到這個問題。私人數據成員不會被記住,並且畢竟是一個NULL或一個糟糕的指針。

+0

如果這就是'NodeManager',那麼您只是試圖重新創建一個非常有限的智能指針。 – chris

+0

我建議您查看一些已經發布到互聯網上的鏈接列表的現有示例。 –

+0

數學家已經提供了正確的答案,但我的問題是你爲什麼要編寫你的init函數? – MikeMB

回答

4

問題是您正在嘗試更改指針的值,但您通過傳遞它。因此,它是在您的函數內部更改的副本。

按值傳遞將創建傳遞給該函數的對象的副本,並且在該函數中對其進行的任何更改僅會被編入副本。如果您想使用該功能更改指針,請根據引用傳遞指針。類似於

void initNode(Node* &b) 
{ 
    b = new Node(); 
} 
+0

我想到了。但是,數據並不是真正的價值傳遞點嗎?下一步是什麼?指針指針?我很困惑... – Pilpel

+1

傳遞函數指針是允許函數修改指針**指向的指針的一種好方法,而不是指針本身。您正在顯式地嘗試更改**指針**的值(即更改地址),並且按值傳遞將不會完成您想要的操作。確定它會改變副本的地址,但在函數退出後副本不再存在 – mathematician1975

+1

@Pilpel,除非您使用引用,否則指針將被包含在內,除此之外,所有東西都會被值傳遞。指針的值是一個地址。複製地址意味着兩個指針都可以訪問該地址處的數據,但更改存儲在一個副本中的地址不會影響另一個副本中存儲的地址。 – chris