一个类中被另一个类使用的向量无法存储项目

Posted

技术标签:

【中文标题】一个类中被另一个类使用的向量无法存储项目【英文标题】:A vector in one class being used by another class is failing to store items 【发布时间】:2020-05-06 11:20:20 【问题描述】:

我有一个 Graph 类,它使用来自文件的信息填充了 Person 类型(另一个类)的 Population 向量。 person 类有一个 Conns 向量,它存储了这个人接触过的所有人。 Graph 类还在 Population 向量中的每个 Person 中填充 Conns 向量。 代码没有给我任何错误,但是当我打印人口向量中人的 Conns 向量中的内容时我什么也没得到

这是 Person 类中的向量以及它是如何添加到其中的

//Person.h
private:
   std::vector<Person> conns;
public:
   void addConn(Person person);
   void printConns();

//Person.cpp
void Person::addConn(Person person)
    conns.push_back(person);


void Person::printConns()
    if (conns.empty())
        cout << "There are no connections for " << name << endl;
    else
        for (int i = 0; i < conns.size(); i++)
            cout << getName() << "-------" << conns[i].getName() << endl;
        
    


这就是 Graph 类以及它如何在每个 Person 中填充 Conns 向量的方式

//Graph.h
private:
   std::vector<Person> population;
   void populate(std::string fileName);
   void addConnections(std::string fileName);
public:
   Graph(std::string pop_file, std::string conn_file);
   Person findPerson(std::string name);

//Graph.cpp
Graph::Graph(string pop_file, string conn_file)
   populate(pop_file); //Add people to the population vector
   addConnections(conn_file); //Add the connections to the respective people


void Graph::addConnections(string fileName)
//The file is read and a while loop is used to retrieve info[0] and //info[1] from the file

   Person contacter = findPerson(info[0]); //Get the person object of the "contacter"
   Person contactee = findPerson(info[1]); //Get the person object of the "contactee"

   //Add the connection to the person
   contacter.addConn(contactee)



//This method is used to retrieve a person object from a person vector
Person Graph::findPerson(string name)
    if (population.empty())
        cout << "Empty vector does not contain any one!" << endl;
    else
        for (int i =0; i < population.size(); i++)

            //Check if the names are equal and return the person object
            if (population[i].getName().compare(name) == 0)
                return population[i];
            
        
    

注意:当我在添加到 Conns 向量之前和之后在 addConnections() 中打印出 Contacter 和 Contactee 时,我得到了正确的信息

我从主文件的图表中打印人口和 conns 向量,但这是我得到的结果

int main()
   Graph graph(pop_file, conn_file);
   graph.printPop(); //Prints the info of the people in the population vector
   for (int i = 0; i < graph.getPop().size(); i ++)
       graph.getPop()[i].printConns();  //getPop() returns the population vector
      
   return 0;

输出: 姓名:阿德里安娜 年龄:12 传播概率:0.32

姓名:罗伯特 年龄:85 传播概率:0.1

姓名:加里 年龄:47 传播概率:0.45

Adrienne 没有人脉

没有罗伯特的连接

Gary 没有人脉

【问题讨论】:

请发帖minimal reproducible example。您的Graph.hprivate: 开头,与Person.h 相同,而其他内容可能与问题无关,可能可以删除 将一个人(addConn() 有一个值参数)复制到另一个Personconns 向量中是否是个好主意?现在,您有一个具有连接的人,该连接可能在另一个人的连接向量中而没有此连接。因此,同一个人可能被认为是不同的。我相信我会在单独的类/变量中使用 Persons 和 Connections 来设计它。 我经常在两个不同的容器中看到带有节点和边的图。在您的情况下,人员是节点,连接是边缘。而且,我会考虑连接是否应该是双向的。 (不过,如果 A 知道 B,那么这并不一定意味着 B 也知道 A。- 这很棘手。) ;-) 【参考方案1】:
Person contacter = findPerson(info[0]); //Get the person object of the "contacter"
Person contactee = findPerson(info[1]); //Get the person object of the "contactee"

//Add the connection to the person
contacter.addConn(contactee)

contacterpopulationPerson 的本地副本,不是同一个对象。所以它添加了一个联系人,然后在处被销毁,而population的元素根本没有改变。

此外,如果找不到此人,您的 findPerson 将缺少 return 声明。确保启用并阅读编译器警告,因为它们应该报告这个严重的问题。

您需要一个指针或引用来使用来自容器或以其他方式存储在其他地方的对象。由于findPerson 可能实际上找不到Person,因此可能为空的指针可能是最简单的。

//This method is used to retrieve a person object from a person vector
Person* Graph::findPerson(string name)
    if (population.empty())
        cout << "Empty vector does not contain any one!" << endl;
    else
        for (int i =0; i < population.size(); i++)

            //Check if the names are equal and return the person object
            if (population[i].getName().compare(name) == 0)
                return &population[i]; // *** NOTE THE &
            
        
    
    return nullptr; // *** ADDED


void Graph::addConnections(string fileName)
//The file is read and a while loop is used to retrieve info[0] and //info[1] from the file

   Person* contacter = findPerson(info[0]); //Get the person object of the "contacter"
   Person* contactee = findPerson(info[1]); //Get the person object of the "contactee"

   if (contacter && contactee) 
       //Add the connection to the person
       contacter->addConn(*contactee)
   

【讨论】:

以上是关于一个类中被另一个类使用的向量无法存储项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个类中调用类类型的向量?

当指针指向的对象被另一个类的实例删除时重新分配指针

在 C++ 类中引用向量

设置者不更改类中向量的数据

使用向量存储实体

编译类型向量类的私有成员时出错 - C++ [重复]