0

重複の可能性:
テンプレートをヘッダーファイルにのみ実装できるのはなぜですか?

私は以前にこの壁に遭遇しましたが、それを修正する方法がわかりません。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;

エラーが発生します。ヘルプ?

4

3 に答える 3

3

テンプレート クラスを操作するときは、クラスの実装と宣言を同じファイルに配置する必要があります。

コンパイラは、テンプレート クラスが使用されるのと同じ場所でコードを生成する必要があります。

テンプレート クラス コンストラクターでの動的割り当て

このようにできます。

template <typename T>
class myClass
{
   //public and private interface. 
} ;

//Here the implementation of the interface goes, just beneath the declaration.
于 2012-09-24T18:04:16.013 に答える
1

次のようなテンプレート化された関数を書くとき

template <typename Type>
BinaryTree<Type>::BinaryTree(){

    root = NULL;
}

コンパイラは、テンプレート引数のインスタンス化を確認するまで、実際にはその関数のコードを生成しません。

BinaryTree<char>::BinaryTree();がないのはそのためです。コンパイラはこのコードを生成しませんでした! これは、charインスタンスが、このテンプレート関数が定義されている場所とは別のコンパイル ユニット (オブジェクト ファイル) にあるためです。

これを修正するには、 のすべてのメンバー関数main()を定義する同じファイルに関数を配置するか、クラスを宣言するヘッダー ファイルにメンバー関数を配置します。BinaryTree

于 2012-09-24T18:07:50.047 に答える
0

このエラーは、リンカーがその型のコンストラクターの定義を見つけられなかったことを意味します。テンプレート化されたコードの主な原因は、関数の定義 (この場合はコンストラクター) がインスタンス化の代わりに利用できず、明示的なインスタンス化が実行されなかったことです。簡単な解決策は、ヘッダーにテンプレートの定義を提供して、それらを利用できるようにすることです。

于 2012-09-24T18:06:08.790 に答える