【问题标题】:Creating a template class object using a template constructor使用模板构造函数创建模板类对象
【发布时间】:2013-09-23 17:06:18
【问题描述】:

我在从模板类创建类对象时遇到问题,我需要构造函数也是模板并在创建对象时接受参数。但是,当我尝试创建对象时,我收到一条错误消息,指出我正在引用不存在的内容。

这是我的代码:

using namespace std;
#include <cstdlib>

template <class Node_Type>
class BinaryTree 
{
public:
    BinaryTree(Node_Type);
    BinaryTree(Node_Type, Node_Type);
    BinaryTree(Node_Type, Node_Type, Node_Type);
    bool isEmpty();
    Node_Type info();
    Node_Type inOrder();
    Node_Type preOrder();
    Node_Type postOrder();


private:
    struct Tree_Node
{
    Node_Type Node_Info;
    BinaryTree<Node_Type> *left;
    BinaryTree<Node_Type> *right;
};

Tree_Node *root;

};

#endif

还有我的 .cpp:

template <class Node_Type>
BinaryTree<Node_Type>::BinaryTree(Node_Type rootNode) {

    root = rootNode;
    root->left = NULL;
    root->right = NULL;

}

.cpp 还有更多内容,但只是其他函数成员无关紧要。我上面显示的构造函数是我无法工作的。

在我的主要部分中,我试图通过调用来声明我的对象:

BinaryTree<char> node('a');

但是当我尝试这个时,我收到一条错误消息:

undefined reference to `BinaryTree<char>::BinaryTree(char)'

这两天我一直在尝试解决这个问题。我在 Google 上搜索了我能想到的所有主题,并在没有帮助的情况下阅读了 Stack Overflow 和其他来源的无数示例。谁能解释我的问题是什么?我知道如何做我的项目,如果 C++ 中的语法不是那么荒谬,我现在已经完成了。提前致谢!

【问题讨论】:

  • 问题的答案是完全编译器告诉你的。 Tree_Node* 不是 char
  • 简短且不精确:因为您的函数主体依赖于 .cpp 文件中的模板。它需要与您的 .h 文件一起直接在您的类定义中,或者如果您不喜欢将它放在那里,因为它更易于阅读,请将函数声明为 inline 并将其移到类定义之外, 在同一个文件中或在您包含在 .h 中的 .hpp
  • @WhozCraig 是对的 root 的类型是 Tree_Node* 而不是 char
  • @StephenFish 这也不对,但没关系。是你的葬礼。您的根指针和树节点左右指针全部未初始化。
  • @t.niese 当然是。我看到的错误是一个完全不同的错误(奇怪的是,OP的编译器显然让它通过了,而我的......正在展示你所描述的内容。当他回答“我将'root = rootNode'更改为'root-> Node_Info = rootNode',它现在工作得很好。”我畏缩了。走出一个未定义的行为,然后进入另一个不同的行为。

标签: c++ class templates constructor


【解决方案1】:

您可以在另一个 cpp 文件中强制实例化模板。

BinaryTree<char>;
BinaryTree<int>;
BinaryTree<double>;

这样所有函数都不需要在头文件中。 有些人将扩展名 .inl 用于具有模板实现的文件。所以 .inl 文件仅在实例化不存在时才需要。

【讨论】:

    【解决方案2】:

    模板代码在实例化时应该是可见的,这意味着函数的定义也必须在标头中。

    【讨论】:

      【解决方案3】:

      解决方案:您不能将模板实现与头文件分开。简单地不要使用 cpp 文件并将定义放在头文件(.h 文件)中。

      为什么?这是因为 cpp 文件可以成为预编译源,而模板是编译时对象;因此,除非指定,否则编译器无法决定使用哪种类型。因此,只需将所有模板未定义的实现放在头 .h 文件中。

      【讨论】:

      • 虽然这是一个正确的陈述,但在in this question 中得到了广泛的介绍,无论如何最终都会成为一个问题,它不是 OP 关于特定错误的问题的答案正在接收消息。
      • @WhozCraig 你确定吗?错误信息似乎是在抱怨构造函数未定义,而不是构造函数定义不正确。
      • @AlanStokes 实际上,它的 both,但你是对的,我会相应地向 Samer 发送一个赞成票(实际上是他们三个)。 OP 的代码在最终发挥作用之前必须进行广泛的变形。感谢您指出。我误读了原来的错误信息。
      猜你喜欢
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 2011-05-08
      • 2019-04-18
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多