使用指针对指针可以解决类成员不更新的问题吗?如果是,如何

Can using pointer to pointer solve non updation of class member as explained here? If yes how?

本文关键字:指针 问题 如何 更新 如果 解决 成员      更新时间:2023-10-16

我有一个C++类">Node",它应该管理NODESEDGESDiGraph

class Node{
string data;
vector<string> links;
map<string, Node> children;
Node* parent;
unsigned int nol;
}
  • 数据是节点id或名称
  • links是从该节点到它们具有边的节点的节点名称的容器
  • children是一个节点映射。类似地图的地图[linkName,Node]
  • parent是父节点,对于root,它是0
  • nol不是孩子

我觉得这不是实现这一点的好方法?接下来,我有一个setLinkTo()函数和一个构造函数,如下所示。

Node(Node* p, string name){
parent = &(*p);
data = name;
nol=0;
(*parent).setLinkTo(this);
}

在第一行中,我尝试发送一个指向父级的指针。这样我以后就可以用它了。我不想发送这个的副本。然后最后一行我将节点添加到node的Parent

void setLinkTo(Node* n){
(*n).parent = this;
nol++;
string link = (*n).data;
map<string, Node>::iterator it;
it = children.find(link);
if(it != children.begin() && it != children.end()){
(*it).second.setLinkTo(n);
}
else{
links.insert(links.end(), link);
children.insert(children.end(), pair<string, Node> (link, (*n)));
}
}

我真的很困惑这个指针。一切如预期。但问题发生在:

main(){
Node root;
Node foo(&root, "foo");
Node bar(&root, "bar");
Node zo(&foo, "zo");
root.displayGraph();
}

首先,它从不显示zo。SECONLY,foo.displayGraph()显示zo。

很明显,您一定对displayGraph()函数感到好奇。

void displayGraph(){
cout<<data<<endl<<"t";
for(map<string, Node>::iterator it=children.begin();it!= children.end(); ++it){
it->second.displayGraph();
}   
}

如果在root.displayGragh()之前向Main()添加行

root.setLinkTo(&foo);

然后,映射有两个foo,尽管它在C++DOCS上说映射键必须是唯一的(我不明白)。zo显示在第二个foo的子级。创建zo本身时,如何更新rootfoo

而且,主要是,我已经在这方面工作了4天,如果我的方法是错误的,包括从链接列表等所有内容的尝试和错误,但由于我无法正确引用边缘而失败得很惨,请告诉我

所以,这是pastebin,http://pastebin.com/RTWQx18i,如果我做错了,请告诉我。我必须完成这项任务,我只需要帮助采取前几步来解决这里的第一个问题(有向图和节点也是如此)http://www.smu.edu/Guildhall/Admissions/PortfolioRequirements/Programming

如果我做得对,那么一个想法是完成sortChildren()函数,对有向图上重复的子对象进行排序,并将子对象集合合并到它们各自的父对象中。

数据成员children是一个map<string, Node>。这意味着当一个元素像你在这里做的那样插入到地图中时:

void setLinkTo(Node* n){
// ... snip
if(it != children.begin() && it != children.end()){
}
else{
children.insert(children.end(), pair<string, Node> (link, (*n)));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    
}
}

插入节点*n副本。这反过来意味着,对该子项的任何后续修改都是在Node副本中完成的,而不是在您想要链接到的Node对象中。

这可能很简单,只需将children更改为map<string, Node*>并相应地更新insert即可。

问题在于:map<string, Node>添加新元素期间的映射可能涉及Node的副本(为该本地对象创建了新映射,所有内容都开始去同步)。

我已经创建了一些修改的工作版本。最重要的变化是保留映射指针而不是对象,但您必须小心已添加对象的解除定位和生命周期。

#include <list>
#include <map>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
class Node
{
public:
string data;
vector<string> links;
map<string, Node*> children;
Node* parent;
unsigned int nol;
Node(Node* p, string name)
{
parent = p;
data = name;
nol = 0;
parent->setLinkTo(this);
}
Node()
:parent(nullptr)
{}
void displayGraph()
{
cout << data << endl << "t";
for (map<string, Node*>::iterator it = children.begin(); it != children.end(); ++it){
it->second->displayGraph();
}
}
private:
void setLinkTo(Node* n)
{
nol++;
const string& link = n->data;
map<string, Node*>::iterator it = children.find(link);
if (it != children.begin() && it != children.end()){
it->second->setLinkTo(n);
}
else{
links.insert(links.end(), link);
children.insert(children.end(), make_pair(link, n));
}
}
};
main(){
Node root;
Node foo(&root, "foo");
Node bar(&root, "bar");
Node zo(&foo, "zo");
root.displayGraph();
}

在您的子映射中,您的值是通过复制存储的Node,对原始对象的所有进一步更改都将丢失。您需要在那里存储指向Node的指针map<string, Node*>