我有三个文件,我想编译并运行它们,但我不断收到一些错误和警告。结构节点的重新定义< 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 :(得分:2)
你在列表中犯的一个错误就是你重新定义了这个结构。
这个定义:
template <class T>
struct Node
{
T info;
T* next;
};
这个定义在两个清单中完成。
编辑:第二件事是你的类方法实现看起来不正确。如果您在使用模板时尝试不拆分cpp和头文件,那么您将获得最大的成功。
答案 1 :(得分: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最多只能出现一次定义。 不要手动重复类型定义(例如,在源文件中)。这是错误的,因为它应该是:没有人想要复制粘贴错误。
函数成员 definitions 通常出现在源文件中,除非它们是模板的成员。在后一种情况下,将它们放在标题中更简单(它们也不必是内联的)。
您可以在SO,书籍或互联网上的其他地方了解编译模型的详细信息。搜索“模板定义”或“一个定义规则”(或ODR)可以提供帮助。
答案 2 :(得分:0)
首先,在标题中,从'struct Node * top;'行中删除'struct'。在C ++中,结构几乎与类相同,唯一的区别是结构成员默认是公共的,而类成员默认是私有的。您不需要使用struct关键字为结构类型添加序列,例如直接C。
其次,你的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
然后在任何使用MyStack实现的文件中'#include“mystack.ipp”'