代码之家  ›  专栏  ›  技术社区  ›  Brandin Jefferson

对“Class<Type>::Class”的未定义引用[重复]

  •  0
  • Brandin Jefferson  · 技术社区  · 13 年前

    可能重复:
    Why can templates only be implemented in the header file?

    我以前遇到过这堵墙,但我不知道如何修复它。在g++中,每当我试图创建BinaryTree类的对象时,我都会遇到这个错误:

    /home/bej0843/cs261/Assignment1/main.cpp:9: undefined reference to `BinaryTree<char>::BinaryTree()'
    

    以下是头文件的代码:

    #ifndef BINARYTREE_H
    #define BINARYTREE_H
    #include <iostream>
    #include <cstring>
    #include <stack>
    using namespace std;
    
    
    
    template<typename Type>
    class BinaryTree
    {
        public:
            struct TreeNode
            {
                    Type nodeinfo;
                    BinaryTree<Type> *left;
                    BinaryTree<Type> *right;
            };
            BinaryTree();
            void setInfo(Type a);
            void setSubtree(Type a);
            bool isEmpty();
            Type Info();
            void inOrder();
            void preOrder();
            void postOrder();
            virtual ~BinaryTree();
        protected:
            TreeNode *root;
            stack<TreeNode*> s;
            stack<TreeNode*> temp;
        private:
          void postOrder(TreeNode *r);
    };
    
    
    #endif  /* BINARYTREE_H */
    

    下面是它的实现代码:

    #include "BinaryTree.h"
    
    template <typename Type>
    BinaryTree<Type>::BinaryTree(){
    
        root = NULL;
    }
    
    template <typename Type>
    void BinaryTree<Type>::setInfo(Type a){
      root->nodeinfo = a;
      root->left = NULL;
      root->right = NULL;
      s.push(root);
    }
    
    template <typename Type>
    void BinaryTree<Type>::setSubtree(Type a){
      root->nodeinfo = a;
      root->left->root = s.top();
      s.pop();
      root->right->root = s.top();
      s.pop();
      s.push(root);
    }
    
    template <typename Type>
    bool BinaryTree<Type>::isEmpty(){
      return (root==NULL);
    }
    
    template <typename Type>
    Type BinaryTree<Type>::Info(){
      return root->nodeinfo;
    }
    
    template <typename Type>
    void BinaryTree<Type>::inOrder(){
    
      TreeNode *c;
      c = s.top();
    
      while (c!=NULL || (!temp.empty())){
        if (c!=NULL)
        {
        temp.push(c);
        c = c->left;
        }
        else{
          c = temp.top();
          temp.pop();
          cout << c->nodeinfo +" ";
          c = c->right;
        }
      }
    
    }
    
    template <typename Type>
    void BinaryTree<Type>::postOrder(){
      postOrder(s.top());
    }
    
    template <typename Type>
    void BinaryTree<Type>::postOrder(TreeNode *r){
      temp.push(s.top());
      TreeNode *c = temp.top();
      s.pop();
      postOrder(c->left->root);
      postOrder(c->right->root);
      cout << c->nodeinfo + " ";
    
    }
    
    template <typename Type>
    void BinaryTree<Type>::preOrder(){
      TreeNode*c = s.top();
      while (c!=NULL||(!temp.empty())){
        if (c!=NULL){
          cout << c->nodeinfo + " ";
          temp.push(c);
          c=c->left;
        }
        else{
          c=temp.top();
          temp.pop();
          c=c->right;
        }
      }
    }
    
    template <typename Type>
    BinaryTree<Type>::~BinaryTree(){
    
    }
    

    总的来说,我称之为:

    BinaryTree<char> tree;
    

    并得到错误。帮助

    3 回复  |  直到 9 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    使用模板类时,必须将类的实现和声明放在同一个文件中。

    编译器需要在使用模板类的同一位置生成代码。

    Dynamic Allocation in Template Class Constructor

    你可以这样做。

    template <typename T>
    class myClass
    {
       //public and private interface. 
    } ;
    
    //Here the implementation of the interface goes, just beneath the declaration.
    
        2
  •  1
  •   chrisaycock spacemanspiff    13 年前

    当您编写模板化函数时

    template <typename Type>
    BinaryTree<Type>::BinaryTree(){
    
        root = NULL;
    }
    

    编译器在看到模板参数的实例化之前,实际上不会为该函数生成代码。

    这就是为什么没有 BinaryTree<char>::BinaryTree() ;编译器从未为此生成代码!原因是你 char 实例位于一个单独的编译单元(对象文件)中,从该编译单元中定义该模板函数。

    要解决此问题,请将 main() 在定义所有 BinaryTree 的成员函数,或者将成员函数放在声明该类的头文件中。

        3
  •  0
  •   David Rodríguez - dribeas    13 年前

    该错误表示链接器未找到该类型的构造函数的定义。模板化代码中的主要原因是函数(在本例中为构造函数)的定义不可用于实例化,并且没有执行显式实例化。简单的解决方案是在标题中提供模板的定义,使其可用。