.h
#ifndef QUEUE_H
#define QUEUE_H
#include<iostream>
template<class T>
class FQueue
{
private:
T fq[10];
public:
\
FQueue(int qs ); //给参数提供默认值
~FQueue();
bool isempty() const;
bool isfull() const;
int queuecount() const;
bool inqueue(const T &item);
bool dequeue(const T &item);
};
void show(); //普通函数这样是没有问题的
//下面这个是原型在这h.定义在cpp中
template<class T> void shimobanhwai(T a);
//下面这样是对的,都放在.h文件中
template<class T> void shimobanhnei(T a)
{
std::cout << "a is " << a << std::endl;
}
#endif // QUEUE_H
.cpp
#include"queue.h"
#include<iostream>
using namespace std;
template<class T>
FQueue<T>::FQueue(int qs) //这样也不行,必须放在.h中,否则当建立对象时还是会出现未定义
{
T* fqp = new T[qs];
}
template<class T>
FQueue<T>::~FQueue() //class名字后面别忘了加<T>,这是我经常忘的
{}
template<class T>
bool FQueue<T>::isempty() const
{}
template<class T>
bool FQueue<T>::isfull() const
{}
template<class T>
int FQueue<T>::queuecount() const
{}
template<class T>
bool FQueue<T>::inqueue(const T &item)
{}
template<class T>
bool FQueue<T>::dequeue(const T &item)
{}
void show()
{
cout << "Am i right?" << endl;
}
template<class T>
void shimobanhwai(T a)
{
cout << "a is " << a << endl;
}
Main.cpp
#include <iostream>
#include"queue.h"
using namespace std;
//模板函数、模板类
//新发现,模板不能分.h.cpp
int main()
{
shimobanhnei(5);
//shimobanhwai(5);//出错
show();
// why(3);
cout << " bye!" << endl;
cin.clear(); //清楚标志位
while (cin.get() != '\n')
continue; //清楚输入流数据
return 0;
}
stackoverflow上我觉得比较经典的解释
Q:
Why can templates only be implemented in the header file?
Because when instantiating a template, the compiler creates a new class with the given template argument. For example:
template<typename T>
struct Foo
{
T bar;
void doSomething(T param) {/* do stuff using T */}
};
// somewhere in a .cpp
Foo<int> f;
When reading this line, the compiler will create a new class (let's call it FooInt
), which is equivalent to the following:
struct FooInt
{
int bar;
void doSomething(int param) {/* do stuff using int */}
}
Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int
). If these implementations were not in the header, they wouldn't be accessible, and therefore the compiler wouldn't be able to instantiate the template.
A common solution to this is to write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.
// Foo.h
template <typename T>
struct Foo
{
void doSomething(T param);
};
#include "Foo.tpp"
// Foo.tpp
template <typename T>
void Foo<T>::doSomething(T param)
{
//implementation
}
This way, implementation is still separated from declaration, but is accessible to the compiler.
Another solution is to keep the implementation separated, and explicitly instantiate all the template instances you'll need:
// Foo.h
// no implementation
template <typename T> struct Foo { ... };
//----------------------------------------
// Foo.cpp
// implementation of Foo's methods // explicit instantiations template class Foo<int>; template class Foo<float>; // You will only be able to use Foo with int or float
If my explanation isn't clear enough, you can have a look at the C++ FaqLite on this subject.