2015-04-20 47 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