c ++将指针从构造函数传递给构造函数

时间:2018-05-26 21:43:53

标签: c++ pointers

我正在学习C ++,我创建了3个类:NodeEditor,Node,NodeIO。

编辑器本质上包含一个节点向量,每个节点都有一个NodeIO实例的向量。

我希望每个班级都能够引用“所有者”。

NodeIO构造函数基本上从Node接收一个指针,Node接受一个指向编辑器的指针。

class NodeEditor {
    NodeEditor() {
        ...push_back(Node(this));
    }
}

class Node {
    NodeEditor* owner;
    Node(NodeEditor* _owner) : owner{ _owner } {
        ...push_back(NodeIO(this));
    }
}

class NodeIO {
    Node* owner;
    NodeIO(Node* _owner) : owner{ _owner } { }
}

然后我需要稍后使用_owner指针。

当我在项目中尝试这个时,首先_owner指针指向正确的位置,但是一旦我需要稍后检索它,实际的对象就不再存在于该指针位置。

允许这种布局工作的我有哪些选择?在这种情况下,是否会有更多推荐的模式。

3 个答案:

答案 0 :(得分:1)

您尚未显示任何复制构造函数。由此,我假设您依赖于编译器提供的默认复制构造函数。这是你问题的根源。

使用时:

NodeEditor
<{1>}中的

,您正在存储Node(this)的副本。但是,如果NodeNodeIO没有正确实现的副本构造函数,NodeIONode对象中的std::vector个对象将指向{ {1}}无效的对象 - 临时Node对象。

这是一个显示问题的示例程序。

Node

输出:

#include <iostream>
#include <vector>

struct Node;

struct NodeIO {
   Node* owner;
   NodeIO(Node* _owner) : owner{ _owner } { }
};

struct NodeEditor;

struct Node {
   NodeEditor* owner;
   Node(NodeEditor* _owner) : owner(_owner)
   {
      std::cout << (void*)this << std::endl;
      nodeIOList.push_back(NodeIO(this));
      nodeIOList.push_back(NodeIO(this));
   }

   std::vector<NodeIO> nodeIOList;
};

struct NodeEditor {
   NodeEditor()
   {
      nodeList.push_back(Node(this));
      nodeList.push_back(Node(this));
   }
   std::vector<Node> nodeList;
};

int main()
{
   NodeEditor editor;
   for ( auto& node : editor.nodeList )
   {
      std::cout << (void*)(&node) << std::endl;
      for (auto& nodeIO : node.nodeIOList )
      {
         std::cout << (void*)(nodeIO.owner) << std::endl;
      }
   }
}

输出清楚地显示了使用0x7ffe53d34c30 0x7ffe53d34c50 0xae10c0 0x7ffe1af7a2a0 0x7ffe1af7a2a0 0xae10e0 0x7ffe1af7a2c0 0x7ffe1af7a2c0 构造的Node对象的指针值以及Node(this)对象的指针值,这些对象存储在{{ 1}}。请注意,Node对象仍指向临时std::vector<Node>个对象。它们是NodeIO中的悬空指针。

我尝试了快速修复,但是没有用。我需要再多做一点。

这是一个适用于默认复制构造函数的解决方案。它使用Nodemain代替std::vector个对象。

std::shared_ptr

输出:

std::vector

答案 1 :(得分:1)

向向量添加内容时, all 向量的元素可能会移动。因此,当您添加Node时,所有现有NodeIO s&#39;所有者指针无效。

要处理此问题,您需要

  • 使用其他数据结构并禁用Node副本和移动构造函数,或
  • Node的移动构造函数中,更新其包含的所有owner的{​​{1}}指针,并确保构建新的NodeIO如果您调用NodeIO复制构造函数,则正确无误。

根据您存储Node的方式,您应该对它们执行相同操作。

答案 2 :(得分:0)

检查NodeEditor对象和Node Objects和NodeIo对象的生命周期。 使用new运算符创建动态对象,或确保NodeEditor和Node和NodeIo的实例化发生在同一范围内。 检查是否保留了NodeEditor对象的Node容器的副本,并在释放NodeEditor对象后使用它。