初始化在构造函数中实现自身的类模板

Posted

技术标签:

【中文标题】初始化在构造函数中实现自身的类模板【英文标题】:Initializing a class template that implements itself in the constructor 【发布时间】:2016-12-10 23:01:25 【问题描述】:

我对使用模板和一般的 STL 比较陌生。仍在做我的研究,但遇到了一门我很难理解的课程。我找到了一个我想修改的TreeNode implementation,但我在初始化对象时遇到了问题。

在构造函数中,参数之一是对自身的引用。但是,如果从未创建过父节点,你怎么能传递对父节点的引用呢?

TreeNode(TreeNode<T>* parent, T data);

任何方向都会很好。我想了解有关此构造的更多信息。

谢谢

【问题讨论】:

第一个参数好像是一个指向父节点的指针。我认为您必须为树的根提供nullptr @nickie 我试了一下,它奏效了。让我现在就做我的耻辱...... 呵呵,干杯... :-) @nickie 你应该把你的评论变成答案! 【参考方案1】:

好像第一个参数是一个指向父节点的指针。 (不仅因为参数的名称是parent,还因为它在linked implementation 中的使用方式,例如,参见方法addChild,该方法将此参数设置为this。)

因此,构造树的根应该有一个nullptr 来代替父级。

TreeNode<int>* root = new TreeNode<int>(nullptr, 42);

随后,可以将其他节点添加为现有节点的子节点:

TreeNode<int>* leftChild = new TreeNode<int>(root, 17);
TreeNode<int>* rightChild = new TreeNode<int>(root, 37);
TreeNode<int>* rightGrandChild = new TreeNode<int>(rightChild, 64);

生产树:

顺便说一句,链接的实现提供了方法getChildaddChild 用于获取/添加现有节点的子节点。使用这两个,上面的树可以构造如下:

TreeNode<int>* root = new TreeNode<int>(nullptr, 42);
root->addChild(17);
root->addChild(37);
root->getChild(1)->addChild(64);   // add to root's child[1]

恕我直言,它似乎缺少一种在不暴露底层实现的情况下构造根树的方法(即,将指针指向父节点的类构造函数)。我建议将构造函数设为私有并添加一个静态方法:

template <class T>
static TreeNode<T>* TreeNode<T>::makeRoot (const T& data) 
  return new TreeNode<T>(nullptr, data);

使用它,上面的树可以使用 TreeNode 作为 ADT 来构造:

TreeNode<int>* root = TreeNode<int>::makeRoot(42);
root->addChild(17);
root->addChild(37);
root->getChild(1)->addChild(64);   // add to root's child[1]

【讨论】:

以上是关于初始化在构造函数中实现自身的类模板的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中实现的接口中进行构造函数重载?

是否可以定义指向构造函数的函数指针?

如何在派生类中实现类的基本函数

C++ 为类模板提供初始化列表构造函数

Javascript 实现的类属性私有化

如何使用工厂构造函数在 Dart 中实现单例模式?