图形结构-指针是坏的吗? 我在C++中实现了一个路径结构的图形结构。p>

图形结构-指针是坏的吗? 我在C++中实现了一个路径结构的图形结构。p>,c++,pointers,C++,Pointers,创建新边或节点时,它将存储在单独的向量中,以便稍后由graph类的析构函数删除。我使用指针是因为它们提供了简单的图形导航;我可以通过简单地比较节点的地址来轻松测试节点的身份,或者通过创建指针向量来创建路径,然后直接使用这些指针在图中导航 struct Edge { Node* from; Node* to; } struct Node { Data data; std::vector<Edge*> outEdges; std::vector

创建新边或节点时,它将存储在单独的向量中,以便稍后由graph类的析构函数删除。我使用指针是因为它们提供了简单的图形导航;我可以通过简单地比较节点的地址来轻松测试节点的身份,或者通过创建指针向量来创建路径,然后直接使用这些指针在图中导航

struct Edge
{
    Node* from;
    Node* to;
}

struct Node
{
    Data data;

    std::vector<Edge*> outEdges;
    std::vector<Edge*> inEdges;
}
struct-Edge
{
节点*来自;
节点*至;
}
结构体类型
{
数据;
std::向量路由;
向量不等式;
}
我读过一些关于指针如何不好的文章,应该避免使用或用智能指针代替它们(但即使是它们也应该避免)。或者优秀的程序员根本不使用它们(除了例外)。我知道它们是内存泄漏、安全风险和总体风险的来源,很难正确管理(特别是在多线程应用程序中)

我的问题是:在这种情况下,指针方法是坏的吗

编辑1: 我在哪里读到的关于指针(smart)应该避免的问题。

在他的回答的第二部分:

    “C++中指针的使用是不必要的。” ……现代C++习语通常不需要指针…… 对于了解现代C++的人来说,很明显,很少需要任何指针(智能或原始的;除非将它们用作迭代器)。
      我要重复一遍。指针还不错。用友好的黄色字母(C)和别针打印在墙上。它们非常有用。我从来没有见过一个专业的C++程序,它完全避免了指针。p> 管理自己的指针通常很糟糕,除非您使用的是指针管理器

      无约束的标准内存分配可能是高性能应用程序的瓶颈,但指针不是标准内存分配的中文名称

      指针不是内存泄漏或安全风险的来源。指针并不难管理(一般来说,编写好的程序并不难)


      如果您不想使用指针,您选择了错误的语言。

      我要重复一遍。指针还不错。用友好的黄色字母(C)和别针打印在墙上。它们非常有用。我从来没有见过一个专业的C++程序,它完全避免了指针。p> 管理自己的指针通常很糟糕,除非您使用的是指针管理器

      无约束的标准内存分配可能是高性能应用程序的瓶颈,但指针不是标准内存分配的中文名称

      指针不是内存泄漏或安全风险的来源。指针并不难管理(一般来说,编写好的程序并不难)


      如果不想使用指针,则选择了错误的语言。

      只要已添加的节点不再被删除,就可以为
      边缘
      类使用普通指针。您仍然可以完整删除整个图形。如果您的图形经常发生变异,我建议对边使用
      std::weak_ptr

      但是,类
      Edge
      已完全过时

      struct Node
      {
          Data data;
          std::vector<Node*> edges;
      }
      
      struct节点
      {
      数据;
      向量边;
      }
      

      这对于有向图和无向图是足够的。在这两种情况下,您只需要记录输出边。在无向图中,您必须记录两个节点中的边(指针指向另一个方向)。

      只要已添加的节点不再被删除,对
      类使用普通指针即可。您仍然可以完整删除整个图形。如果您的图形经常发生变异,我建议对边使用
      std::weak_ptr

      但是,类
      Edge
      已完全过时

      struct Node
      {
          Data data;
          std::vector<Node*> edges;
      }
      
      struct节点
      {
      数据;
      向量边;
      }
      

      这对于有向图和无向图是足够的。在这两种情况下,您只需要记录输出边。在无向图中,您必须记录两个节点中的边(指针指向另一个方向)。

      出于性能原因,为什么尽可能避免使用指针
      因为必须在内存中跟踪它们,所以它们的缓存局部性非常差

      一个对象可以有多少所有者
      只能有一个
      除非它是共享的(这才是真正的单一所有者)。因此,您可以使用无所有者指针,只要您只遵循它们,而不删除或转移它们的所有者身份

      如果我指向移动的对象,指针会神奇地更新吗
      不如果将向量用于存储,并且超出其容量,它将重新定位,从而使指向它的所有指针无效。如果你的确信你有足够的容量,你可以使用指针

      在这种情况下,我会考虑下面的结构,指向内存的指针仅仅是内存中的索引,那么为什么不使用索引本身呢?
      struct Edge {
          // index into allNodes
          uint32_t from;
          uint32_t to;
      }
      
      std::vector<Edge> allEdges;
      
      struct Node {
          Data data;
      
          // index into allEdges
          std::vector<uint32_t> outEdges;  // sort on to
          std::vector<uint32_t> inEdges;   // sort on from
      }
      
      std::vector<Node> allNodes; // contains all nodes
      
      struct-Edge{
      //索引到所有节点
      uint32_t from;
      uint32_t to;
      }
      std::向量allEdges;
      结构节点{
      数据;
      //小巷索引
      std::vector outEdges;//排序到
      std::vector inEdges;//从开始排序
      }
      std::vector allNodes;//包含所有节点
      
      如果不需要遍历所有边,则更为激进

      struct Node {
          Data data;
      
          // index into allNodes
          std::vector<uint32_t> outEdges; // sort
          std::vector<uint32_t> inEdges;  // sort
      }
      
      std::vector<Node> allNodes; // contains all nodes
      
      struct节点{
      数据;
      //索引到所有节点
      std::vector outEdges;//排序
      std::vector inEdges;//排序
      }
      std::vector allNodes;//包含所有节点
      
      你不能这样做的是:
      a) 删除任何节点/边并向上移动其余节点/边。 b) 移动其中任何一个,包括 c) 分类

      如果删除了两个节点中的边,请记住将其删除

      如果在每个向量中都有很多边,那么可能需要对它们进行排序,这样就可以使用二进制搜索来查找