如何在运行时使用构造函数初始化在类中私有的数组?

时间:2019-01-04 21:21:32

标签: c++ class constructor

当我在名为visited的类中的私有访问中创建了一个指针时,我就创建了Graph类。在构造函数中,我在所有位置都将数组初始化为零,但是当我在另一种方法中检查所有值是否均为零时,它在数组中显示垃圾值,但是当我在构造函数中自己打印时,则显示所有零。

#include<iostream>
#include<vector>
#include<list>
using namespace std;

class Graph {
private:
  int vertices,edges;
  vector <list<int>> graph;
  vector <int> vs;
  int *visited;
public:
  Graph (int vertices)
  {
    this->vertices = vertices;
    list <int>l;
    for (size_t i = 0; i < vertices; i++) {
      graph.push_back(l);
      vs.push_back(i);
    }
    edges=0;
// #######  made a new array, initialized all values with zeroes and assigned it to the instance variable visited  #########
    int a[vertices]={0};
    this->visited = a;
// ########  in the constructor it is showing correct values below  #######
    for (size_t i = 0; i < vertices; i++) {
      std::cout << this->visited[i] << ' ';
    }
    std::cout << '\n';
  }
  virtual ~Graph ()
  {

  }
  void showList()
  {
// just printing the graph in the form of adjacency list 
// it is working fine
    for (size_t i = 0; i < vertices; i++)
    {
      list <int>::iterator p = graph[i].begin();
      std::cout << i ;
      for (; p != graph[i].end() ; p++)
      {
        std::cout << " -> " << *p ;
      }
      std::cout << " -> NULL" << '\n';
    }
// ########  when I am checking the values here then it is printing garbage values 
    for (size_t i = 0; i < this->vertices; i++) {
      std::cout << this->visited[i] << ' ';
    }
  }
  void addEdge(int source, int destination)
  {
    graph[source].push_back(destination);
  }
};

int main()
{
  Graph g(6);
  g.addEdge(0,1);
  g.addEdge(0,2);
  g.addEdge(1,0);
  g.addEdge(1,3);
  g.addEdge(1,4);
  g.addEdge(2,0);
  g.addEdge(2,4);
  g.showList();
  return 0;
}

当我调用showList方法时,它应该打印邻接列表和所有零(名为访问数组的内容)

1 个答案:

答案 0 :(得分:1)

  

我制作了一个Graph类。

是的。

class Graph {
  

我在名为visited的类中的私有访问中创建了一个指针。

是的。

private:
  int *visited;
  

在构造函数中,我已在所有位置将数组初始化为零。

是的。

int a[vertices]={0};

但是我要注意,这是构造函数本地的变量。其他任何方法都不可见。同样,当构造函数完成时,该对象的寿命也将结束。在其生存期结束后访问该数组的任何尝试都是未定义的行为。因此,通过一些偷偷摸摸的机制(例如将其地址保存在指针中)来访问它会导致发生不好的事情。

您在这里偷偷摸摸(非常糟糕):

this->visited = a;
  

但是当我在另一种方法中检查所有值是否均为零时

您正在通过指针visited访问数组。这指向一个不再存在的数组,因为该数组位于另一个函数的本地。

    std::cout << this->visited[i] << ' ';  // This is broken code.
  

它在数组中显示垃圾值

你真倒霉。如果程序崩溃了,并且变得很明显发生了不好的事情,那就更好了。不幸的是,您发现未定义的行为可以做任何事情(包括简单地返回一些随机值)。

  

但是当我在构造函数本身中打印它时,它显示所有零。

它在构造函数中仍然有效,因此访问它不是问题。

那是什么解决办法。

一般而言,指针应避免使用指针(尤其是全新的指针)。您需要首先掌握一些基本概念。

在这种情况下,只需替换:

 int*   visited;

使用

 std::vector<int> visited;

在构造函数中,用适当的零值填充它。