C++ C+中树数据结构的深度复制+;没有样板副本代码?

C++ C+中树数据结构的深度复制+;没有样板副本代码?,c++,c++11,copy-constructor,deep-copy,assignment-operator,C++,C++11,Copy Constructor,Deep Copy,Assignment Operator,假设我使用节点类实现了一个树数据结构: class Node { Node * parent; std::vector<Node*> children; int data_1; std::string data_2; double data_3; ... float data_n; }; 我事先知道指针属性的数量很小,不会改变。但是,非指针属性更大,并且随着我开发程序而波动。因此,我宁愿避免每次添加新属性时都要记住添加此样板代码 (我愿意使用C++11,

假设我使用节点类实现了一个树数据结构:

class Node
{
  Node * parent;
  std::vector<Node*> children;
  int data_1;
  std::string data_2;
  double data_3;
  ...
  float data_n;
};
我事先知道指针属性的数量很小,不会改变。但是,非指针属性更大,并且随着我开发程序而波动。因此,我宁愿避免每次添加新属性时都要记住添加此样板代码


(我愿意使用C++11,但不太热衷于boost)

正如评论中所暗示的那样,您可以将数据包装到结构中,然后只复制一个结构,并在复制构造函数体中处理其余的复制过程:

class Node
{
  Node * parent;
  std::vector<Node*> children;
  //... maybe more

  struct Data {
      int data_1;
      std::string data_2;
      double data_3;
      ...
      float data_n;
  }
  Data data;
  Node( Node const& other) : data( other.data) {
      //... do the rest
  }
};
类节点
{
节点*父节点;
性病媒儿童;
//……也许更多
结构数据{
int数据_1;
std::字符串数据_2;
双数据_3;
...
浮动数据;
}
数据;
节点(节点常数和其他):数据(其他数据){
//…做剩下的事
}
};

您可以将有效负载放在基类中:

struct i {
        i(int a, float b) : a(a), b(b) {}
        int a;
        float b;
};

struct n : i {
        using i::i;
        n(const n&r) : i(r) {}
};

n N {1,1.0};

int main()
{
        n M {0,1.0};
        M=N;
        return M.a;
}

它还有其他优点,我喜欢将内容与结构分离。

如果您只需要一个可以使用的递归容器。它的设计考虑了这些用例。我看到的代码的问题是指向父级的指针。我认为这不能简单地实施。但您将免费获得内存管理。

您可以将所有非指针封装在一个结构中,然后只复制该结构。但会在所有访问中添加一个额外的点。或者,将指针包装在子结构中,并为其提供自己的副本构造函数。类似地,也可以使用
std::tuple
,但这也会使数据访问更加复杂。将指针包装在结构或类中也可能有助于分离关注点。毕竟,如果指针都是相关的(即用于节点遍历),那么将它们捆绑在一起可以让您将它们交给不关心其余数据的函数或算法。很好。因此,这个解决方案需要额外的点来访问:
my\u node->data\u 1
变成
my\u node->data.data\u 1
?有没有一种方法可以模板化和派生这样的类?在
数据
上建立模板似乎很容易,但我无法想象如何从节点派生,因为派生类应该有派生类
子类
,所以我无法在节点内完成深层复制的讨厌部分。(为什么用父指针实现树如此难以捉摸?或者每个人都维护样板副本和
op=
routines?)继承应该用于表示一种关系。在这种情况下,至少应该使用私有继承case@privatedatapublicchannel2这是一个奇怪的限制。我不能说我认为绝对禁止这种技术和所有类似的技术有任何价值。在我看来,你已经深陷“领地”了。(编辑:替换了5分钟后的乱码链接,所以重写)。如果我不想要父指针,我真的需要boost容器吗?stl容器不够用吗?@mangledorf no.请参阅和。只要您需要递归容器,您就有一个不完整的类型。
struct i {
        i(int a, float b) : a(a), b(b) {}
        int a;
        float b;
};

struct n : i {
        using i::i;
        n(const n&r) : i(r) {}
};

n N {1,1.0};

int main()
{
        n M {0,1.0};
        M=N;
        return M.a;
}