C++テンプレートと定義の分離
C++Primer(第4版p 545)は、テンプレートの定義と分離を実現するためにこのような技術を採用している.
Queue.hファイル:
Queue.cppファイル:
1.Queue.hファイルには確かに#include"Queue.cpp"(これは正しい)と書かれています.建設された工事では、Queueはcppは(ディスクディレクトリの下に置かれているが、プロジェクトに参加しないでください)、つまりQueue.cppは直接コンパイルリンクに参加せず、main()だけがコンパイルに参加し、3.main()が存在するファイルでは、#include"Queue.h"が1と3の効果で分離したテンプレート定義と実装をmain()が存在するファイルにマージします.
それでQueue.cpp自体は直接コンパイルしない(main()が存在するファイルのコンパイルに間接的に参加するだけ)ので、再定義エラーも発生しません
Queue.hファイル:
- #ifndef _QUEUE_H_
- #define _QUEUE_H_
-
- template class Queue;
-
- template
- class QueueItem
- {
- friend class Queue ;
- QueueItem( const Type& t ):value(t),next(0) {}
- Type value;
- QueueItem* next;
- };
-
- template
- class Queue
- {
- public:
- Queue():head(0),tail(0) {}
-
- Queue( const Queue& Q ):head(0),tail(0)
- {
- copy_item(Q);
- }
-
- ~Queue()
- {
- destroy();
- }
-
- Type& front()
- {
- return head->value;
- }
-
- const Type& front() const
- {
- return head->value;
- }
-
- void push( const Type& );
- void pop();
- bool empty() const
- {
- return head == 0;
- }
-
- void print();
-
- protected:
- private:
- QueueItem * head;
- QueueItem * tail;
- void copy_item( const Queue& );
- void destroy();
- };
- #include "Queue.cpp"
- #endif
Queue.cppファイル:
- #include "Queue.h"
-
- template
- void Queue ::destroy()
- {
- while ( !empty() )
- {
- pop();
- }
- }
-
- template
- void Queue ::pop()
- {
- QueueItem *ptr = head;
- head = head->next;
- delete ptr;
- }
-
- template
- void Queue ::push( const Type& t )
- {
- QueueItem *ptr = new QueueItem(t);
-
- if ( empty() )
- {
- head = tail = ptr;
- }
- else
- {
- tail->next = ptr;
- tail = tail->next;
- }
- }
-
- template
- void Queue ::copy_item( const Queue& Q )
- {
- QueueItem *ptr = Q.head;
- for ( ; ptr ; ptr++ )
- {
- push( ptr->value );
- }
- }
-
- template
- void Queue ::print()
- {
- while( !empty() )
- {
- cout < < head->value < < endl;
- }
- }
1.Queue.hファイルには確かに#include"Queue.cpp"(これは正しい)と書かれています.建設された工事では、Queueはcppは(ディスクディレクトリの下に置かれているが、プロジェクトに参加しないでください)、つまりQueue.cppは直接コンパイルリンクに参加せず、main()だけがコンパイルに参加し、3.main()が存在するファイルでは、#include"Queue.h"が1と3の効果で分離したテンプレート定義と実装をmain()が存在するファイルにマージします.
それでQueue.cpp自体は直接コンパイルしない(main()が存在するファイルのコンパイルに間接的に参加するだけ)ので、再定義エラーも発生しません