C++ Primer(第四版p545)是采用这样的技术让模板定义和实现分离 

Queue.h文件:
  1. #ifndef _QUEUE_H_   
  2. #define _QUEUE_H_   
  3.   
  4. template  class Queue;   
  5.   
  6. template    
  7. class QueueItem   
  8. {   
  9. friend class Queue ;   
  10. QueueItem( const Type& t ):value(t),next(0) {}   
  11. Type     value;   
  12. QueueItem*  next;   
  13. };   
  14.   
  15. template    
  16. class Queue   
  17. {   
  18. public:   
  19. Queue():head(0),tail(0) {}   
  20.   
  21. Queue( const Queue& Q ):head(0),tail(0)   
  22. {   
  23. copy_item(Q);   
  24. }   
  25.   
  26. ~Queue()   
  27. {   
  28. destroy();   
  29. }   
  30.   
  31. Type& front()   
  32. {   
  33. return head->value;   
  34. }   
  35.   
  36. const Type& front() const   
  37. {   
  38. return head->value;   
  39. }   
  40.   
  41. void push( const Type& );   
  42. void pop();   
  43. bool empty() const   
  44. {   
  45. return head == 0;   
  46. }   
  47.   
  48. void print();   
  49.   
  50. protected:   
  51. private:   
  52. QueueItem * head;   
  53. QueueItem * tail;   
  54. void copy_item( const Queue& );   
  55. void destroy();   
  56. };   
  57. #include "Queue.cpp"   
  58. #endif   
Queue.cpp文件:
  1. #include "Queue.h"   
  2.   
  3. template    
  4. void Queue ::destroy()   
  5. {   
  6. while ( !empty() )   
  7. {   
  8. pop();   
  9. }   
  10. }   
  11.   
  12. template    
  13. void Queue ::pop()   
  14. {   
  15. QueueItem  *ptr = head;   
  16. head = head->next;   
  17. delete ptr;   
  18. }   
  19.   
  20. template    
  21. void Queue ::push( const Type& t )   
  22. {   
  23. QueueItem  *ptr = new QueueItem(t);   
  24.   
  25. if ( empty() )   
  26. {   
  27. head = tail = ptr;   
  28. }   
  29. else   
  30. {   
  31. tail->next = ptr;   
  32. tail = tail->next;   
  33. }   
  34. }   
  35.   
  36. template    
  37. void Queue ::copy_item( const Queue& Q )   
  38. {   
  39. QueueItem  *ptr = Q.head;   
  40. for ( ; ptr ; ptr++ )   
  41. {   
  42. push( ptr->value );   
  43. }   
  44. }   
  45.   
  46. template    
  47. void Queue ::print()   
  48. {   
  49. while( !empty() )   
  50. {   
  51. cout < < head->value < < endl;   
  52. }   
  53. }  

1. 在Queue.h文件的确写有#include "Queue.cpp"(这是对的) 
2. 而建立的工程里面,并不把Queue.cpp包含进来(放在磁盘目录下,但别加入工程),也就是Queue.cpp并不直接参与编译链接,只有main()参加编译, 
3. 在main()所在的文件中,#include "Queue.h" 

由于1和3的效果,使分离的模板定义和实现合并到了main()所在的文件中 

而由于Queue.cpp本身不直接编译(仅间接参与main()所在的文件的编译),所以也不会出现重定义错误