2011-07-04 89 views
0

我有三个文件,我想编译和运行它们,但我不断收到一些错误和警告。重新定义struct Node < 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++编译模型简要指针:

// 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被重用)与包括警卫,你在做什么。守卫在这里,因为定义必须每TU最多出现一次。 不要手动重复类型定义(例如,像您一样在源文件中)。这是错误的,因为它应该是:没有人想复制粘贴错误。

函数成员定义通常出现在源文件中,除非他们是模板的成员。在后一种情况下,将它们放在标题中很简单(它们不必内联)。

您可以在SO,其他书籍或Internet上的其他地方了解编译模型的详细信息。搜索“模板定义”或“一个定义规则”(或ODR)可以提供帮助。

2

错误之一是,你作为它说重新定义了这种结构。

那是定义:

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

这个定义在两个列表来完成。

编辑:第二件事是你的类方法实现看起来不正确。如果您在使用模板时尝试不分割cpp和头文件,那么您将获得最大的成功。

+0

我不需要在两个文件中定义一个结构吗?关于课程呢? –

+1

您只能在每个包含文件中进行一次类型定义。这对结构以及类和其他类型定义代码都很重要。 – fyr

0

首先,在头文件中,从'struct Node * top;'行删除'struct'。在C++中,结构几乎与类相同,唯一的区别是结构成员默认是公共的,而类成员默认是私有的。你不需要像直C中的struct关键字一样写结构类型。

第二,你的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