2011-07-04 13 views
0

私は3つのファイルを持っているので、コンパイルして実行したいが、いくつかのエラーと警告が出てくる。構造体ノード< T>の再定義。テンプレートについてはあまりよく分かりませんが、これは私には正しいと思われます。そして、何が間違っているのか理解しようと多くの時間を費やしました。ありがとう。あなたがリストになかったテンプレートの問題

//mystack.h 
#ifndef MYSTACK_H 
#define MYSTACK_H 

template <class T> 
struct Node 
{ 
    T info; 
    T *next; 
}; 

template <class T> 
class MyStack 
{ 
private: 
    struct Node<T> *top; 
public: 

    void Push(T item); 

    void Pop(); 

    int Top(); 

    void Print(); 
}; 

#endif 

//mystack.cpp 
#include <iostream> 
#include "mystack.h" 

template <class T> 
struct Node 
{ 
    T info; 
    T* next; 
}; 

template <class T> 
class MyStack 
{ 
private: 
    struct Node<T>* top; 

public: 
    void Push(T item) 
    { 
     if(top == NULL) 
     { 
      top = new(struct Node<T>); 
      top->info = item; 
      top->next = NULL; 
     } else 
     { 
      Node<T>* temp; 
      temp = top; 
      top = new(struct Node<T>); 
      top->info = item; 
      top->next = temp; 
     } 
    } 

    void Pop() 
    { 
     if(top == NULL) 
     { 
     } else 
     {  
      Node<T>* temp; 
      temp = top->next; 
      delete top; 
      top = temp; 
     } 
    } 

    int Top() 
    { 
     return top; 
    } 

    void Print() 
    { 
     if(top != NULL) 
     { 
      Node<T>* temp; 
      temp = top; 
      while(temp != NULL) 
      { 
       std::cout << temp << std::endl; 
       temp = temp->next; 
      } 
     } 
    } 
}; 

答えて

0

テンプレートの代わりにクラスを設計していた場合は、タイプを再定義するため、やっていることが間違っています。

しかし、あなたがテンプレートを書いているので、あなたは間違っています。テンプレートを個別にコンパイルすることはできません。 C++のコンパイルモデルに

ブリーフポインタ:あなたがやっているよう(それらが異なるのTUで再利用される場合)

// Definition of Node 
template<typename T> 
struct Node { 
    T info; 
    T* next; // shouldn't that be a Node*? 
}; 

// Definition of MyStack 
template <typename T> 
class MyStack 
{ 
private: 
    Node<T> *top; 
public: 

    // Declarations, but not definitions, of the Mystack function members. 
    void Push(T item); 
    void Pop(); 
    int Top(); 
    void Print(); 
}; 

// Example definition of MyStack::Push 
template<typename T> 
void 
MyStack<T>::Push(T item) 
{ 
    // as before 
} 

型定義は、通常、ヘッダに表示されるとは、警備員が含まれます。ガーディアンはTUごとに最大で1回しか定義されていないため、ここにあります。 タイプ定義を手動で繰り返してはいけません(たとえば、元のファイルのように)。これは間違っているはずです。誰もコピーアンドペーストエラーを欲しません。

関数メンバー定義は通常、彼らはテンプレートのメンバーであるない限り、ソースファイルに表示されます。後者の場合は、ヘッダーに入れるほうが簡単です(インラインである必要はありません)。

SO、ブック、またはインターネット上のコンパイルモデルの詳細を知ることができます。 「テンプレート定義」または「1つの定義ルール」(またはODR)を検索すると役立ちます。

2

1つのミスは、それが言うように、あなたがこのような構造を再定義することです。

は、定義厥:

template <class T> 
struct Node 
{ 
    T info; 
    T* next; 
}; 

この定義は、両方のリストで行われます。

編集:もう1つは、クラスメソッドの実装が正しく表示されないことです。テンプレートを使用している間にcppファイルとヘッダファイルを分割しないようにすると、最も成功します。

+0

両方のファイルに構造体を定義する必要はありませんか?クラスはどうですか? –

+1

すべてのインクルードファイルにタイプ定義を1回だけ含めることができます。これは構造体だけでなく、クラスや他の型定義コードも考慮します。 – fyr

0

まず、ヘッダーで、 'struct Node * top;'行から 'struct'を削除します。 C++の構造体はクラスとほとんど同じですが、構造体のメンバーはデフォルトでパブリックであり、クラスのメンバーはデフォルトでプライベートであるという唯一の違いがあります。ストレートCのようにstructキーワードをstructキーワードの前に置く必要はありません。

第2に、あなたのCPPはすべて間違っています。テンプレートは、必要に応じてコンパイラによってインスタンス化されるため、通常のようにオブジェクトにコンパイルされるCPPファイルには存在しません(テンプレート特殊化とは別に)。あなたは、HPP自体またはより良い一般的な解決IPPファイルを使用することですであなたのテンプレート定義を置くことができ、すなわち

// mystack.ipp 
#ifndef MYSTACK_IPP 
#define MYSTACK_IPP 

#include "mystack.h" 
#include <iostream> 

template <class T> 
void MyStack<T>::Push(T item) 
{ 
    if(top == NULL) 
    { 
     top = new(struct Node<T>); 
     top->info = item; 
     top->next = NULL; 
    } else 
    { 
     Node<T>* temp; 
     temp = top; 
     top = new(struct Node<T>); 
     top->info = item; 
     top->next = temp; 
    } 
} 

template <class T> 
void MyStack<T>::Pop() 
{ 
    if(top == NULL) 
    { 
    } else 
    {  
     Node<T>* temp; 
     temp = top->next; 
     delete top; 
     top = temp; 
    } 
} 

template <class T> 
int MyStack<T>::Top() 
{ 
    return top; 
} 

template <class T> 
void MyStack<T>::Print() 
{ 
    if(top != NULL) 
    { 
     Node<T>* temp; 
     temp = top; 
     while(temp != NULL) 
     { 
      std::cout << temp << std::endl; 
      temp = temp->next; 
     } 
    } 
} 
#endif 

その後の実装を使用するすべてのファイルの「の#include 『mystack.ipp』」 MyStack

関連する問題