值不会在类列表的向量中被修改

Values Don't Get Modified in Vector of List of Class

本文关键字:向量 修改 列表      更新时间:2023-10-16

我是使用STL C++初学者,最近才开始研究向量。我正在尝试构建类对象列表的类型向量的数据结构。

发现每当我尝试在我的类对象变量中进行更改时,更改都会根据需要编写。但是,如果我读回相同的类变量,它们会返回以前的值。

这是我的代码的简化版本,它首先将所有布尔变量值初始化为"0"。

然后,我否定所有布尔值,并观察到变量在反转后得到值"1"。

但是,当我再次显示我的列表时,我看到它们回到了"0"。

这是我使用的代码段:

#include <iostream>
#include <vector>
#include <list>
using namespace std;
class edge{
private:
   bool _id;
public:
   void invert_id()
   {
      _id = !_id;
   }
   bool get_id()
   {
      return _id;
   }
   edge(bool id) //Constructor
   {
      _id = id;
   }
};
void display_list(vector<list<edge> > &adjList);
void negate_list(vector<list<edge> > &adjList);
int main() {
   vector<list<edge> > adjList(2);
   adjList[0].push_back(edge(false));
   adjList[0].push_back(edge(false));
   adjList[1].push_back(edge(false));
   adjList[1].push_back(edge(false));
   adjList[1].push_back(edge(false));
   cout<<endl <<"Original List-->" <<endl;
   display_list(adjList);
   cout<<endl <<"Inverted List-->" <<endl;
   negate_list(adjList);
   cout<<endl <<"List After Inversion-->" <<endl;
   display_list(adjList);
}

以下是我编写的通过引用传递向量的函数:

void display_list(vector<list<edge> > &adjList)
{
 int c=0;
 for (vector<list<edge> >::iterator i=adjList.begin(); i !=adjList.end(); ++i)
 {
    cout<<"AdjList["<< c<<"] IDs =";
    list<edge> li = *i;
    for(list<edge>::iterator iter = li.begin(); iter!= li.end(); ++iter)
    {
       cout<<"  "<<(*iter).get_id();
    }
    cout<<endl;
    c++;
 }
}
void negate_list(vector<list<edge> > &adjList)
{
int c=0;
   for (vector<list<edge> >::iterator i=adjList.begin(); i !=adjList.end(); ++i)
   {
      cout<<"AdjList["<< c<<"] IDs =";
      list<edge> li = *i;
      for(list<edge>::iterator iter = li.begin(); iter!= li.end(); ++iter)
      {
         (*iter).invert_id();
         cout<<"  "<<(*iter).get_id();
      }
      cout<<endl;
      c++;
   }
}

我得到的输出是:

Original List-->
AdjList[0] IDs =  0  0
AdjList[1] IDs =  0  0  0
Inverted List-->
AdjList[0] IDs =  1  1
AdjList[1] IDs =  1  1  1
List After Inversion-->
AdjList[0] IDs =  0  0
AdjList[1] IDs =  0  0  0

如上所示,我无法理解为什么即使将它们更新为"1",这些值也会恢复为"0"。

我在这里缺少什么吗?

list<edge> li = *i;

这是std::list深层副本。您对此std::list所做的任何更改都不会影响原始更改。

这应该可以解决您的问题:

void negate_list(vector<list<edge> > &adjList){
   int c=0;
   for (auto i=adjList.begin(); i !=adjList.end(); ++i){
      cout<<"AdjList["<< c<<"] IDs =";
      for(auto iter = i->begin(); iter!= i->end(); ++iter){
         (*iter).invert_id();
         cout<<"  "<<(*iter).get_id();
      }
      cout<<endl;
      c++;
   }
}

出于同样的原因,negate_list函数通过引用获取其向量参数,函数主体中的li变量必须是引用。

list<edge> li = *i;实际上是在调用 STL 列表类型的复制构造函数,并且如文档所述:

[它] 以相同的顺序构造一个容器,其中包含 [列表] 中每个元素的副本

这就是胡玛姆所说的"深拷贝"的意思。复制edge后,显然会对副本执行任何修改。但是,通过引用引用列表将允许我们通过引用访问原始edge元素,从而修改它们。