【问题标题】:C++ Generic node class will not take nodes of different typeC++ 通用节点类不会采用不同类型的节点
【发布时间】:2014-08-29 07:06:23
【问题描述】:

我正在尝试创建一个通用节点类,它可以存储对其他通用节点的引用,这些节点可以具有不同的数据类型。

template < class T >
class BiTreeNode {
    T d;
    BiTreeNode *parent; //Trying to store a node of different type here
public:
    BiTreeNode(void);
    BiTreeNode(T);
    void setData(T);
    T * getData(void);
    void setParent(BiTreeNode * const); // Error here.
    BiTreeNode * getParent(void);
};

具体错误:

Error 1 error C2664: 'void BiTreeNode<char>::setParent(BiTreeNode<char> *const )' : cannot convert argument 1 from 'BiTreeNode<int> *' to 'BiTreeNode<char> *const ' (File Location) 42 1 P=NP

【问题讨论】:

  • 这行不通,因为如果T1T2 不是同一类型,则BiTreeNode&lt;T1&gt;BiTree&lt;T2&gt; 不是同一类型。但你在问什么?
  • (File Location) 包含 42P=NP 之类的东西? :D
  • @tgmath 没有足够的复活节彩蛋?
  • @juanchopanza 我正在尝试在*parent 中存储另一个不同类型的节点,它给出了一个错误:/
  • 你不能。您将需要所有二叉树节点类型的通用基类。

标签: c++ templates generics tree nodes


【解决方案1】:

不同的模板实例化,即使它们看起来具有相同的名称,也不相关。

模板是为代码重用而设计的,每个具有不同类型的模板实例化实际上是完全不同的类类型,没有多态关系。

BiTreeNode&lt;int&gt;BiTreeNode&lt;char&gt; 是 2 个不同的类,没有共同的基类。如果您只是将 符号作为类名的一部分阅读,则很容易记住这一点。

要做你想要在那里实现的目标,只需让模板类派生自一个公共基类:

class BaseTreeNode
{
};

template < class T >
class BiTreeNode : public BaseTreeNode
{
 T d;
    BaseTreeNode *parent; 

...

}

这样,创建的每个模板类都派生自同一个类,并且您拥有所需的多态性。

【讨论】:

  • 如何从BaseTreeNode *parent 调用特定于 BiTreeNode 的函数。例如:我有一个BiTreeNode n,我想(*n.getParent()).getData()。这是怎么发生的?
【解决方案2】:

template 是一个类工厂:它生成类(不是值:类)。结果类的连接非常少(您可以对它们进行类型模式匹配)。

模板生成类型。

类型生成值。

您不能将指针指向一种类型的值并将其指向不同类型的值,除非通用布局/继承规则允许。这就是你要求做的。

现在你可以在生成的类型之间创建某种关系,但是在实践中继承很少是你想要的,普通的布局也不能给你想要的。 拥有一个共同的父母有时很有用,并且会给你一些你想要的东西。

至于您的语法错误,模板类本身中没有参数列表的模板类的名称隐含地引用了具有“相同”模板参数的模板类。所以在foo&lt;int&gt; 内,foo 隐含地指代foo&lt;int&gt;

您可能正在尝试复制 C++ 中用于泛型的技术:泛型不是模板。模板可以用来生成泛型,但是这个过程非常复杂,你最好编写模板代码来做模板的东西,而不是泛型的东西。即,重新设计。

公共父级意味着您创建一个 base 类,template class 从中继承。使用base* 来引用指向由template 生成的任何类型的任何值的指针。粘贴模板在其中生成的每种类型的通用属性(例如父级base 指针),以便您可以通过base* 指针访问它们。

如果您想访问不常见的属性(如T get_value()),上述内容对您没有帮助。弄清楚如何用 3 类案例(int double 和基础说)解决问题,并查看该技术是否适用于 n+1 类案例。有足够的复杂性,我无法从上面的描述中猜出答案是什么:如果你有这样的属性,请写一个新问题。

【讨论】:

  • 模板实例是什么意思?
  • @Yakk:请注意,“模板的实例”指定生成的类,而不是生成的类的实例。现在找到比“模板实例的实例”更好的措辞......
  • @michaelmitchell 现在应该删除该短语。
  • @quentin 因为你不能有指向类型的指针(呵呵),在特定用途中不可能有歧义,但最好使用更清晰的语言。
  • 我还是很迷茫,您能否提供一个链接,指向进一步讨论这个问题的文章?
猜你喜欢
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-27
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多