一直沒有對 C++ 模闆做過系統的學習,對于 STL 模闆類或者函數,都是查查文檔就直接使用。不過在翻開 STL 代碼的時候,都曾注意到那些模闆是放置在.h檔案中的,至于為何,卻是沒有去想過。
今天在編寫一個動态連接配接庫的時候,才明白其中的原因。比如庫裡面有下面模闆類
template <typename Data>
class concurrent_queue
{
public:
concurrent_queue(unsigned capacity);
~concurrent_queue();
bool push(const Data&);
void pop(Data&, int timeout = -1);
...
};
開始我習慣性的将這個模闆類的實作放在 .cpp 檔案裡面,編譯出來的 .so 都正常。但是在使用這個模闆的時候,就出現問題。
比如
class Message
{
...
}
concurrent_queue<Message *> message_queue;
Message * pMsg = new Message();
message_queue.push(pMsg);
...
那麼在連接配接上面的 .so 時,會出現下面的錯誤
XXX.so: undefined reference to `concurrent_queue<Message*>::push(const Message* &)'
那是因為編譯器無法生成對應 Message *的實作,如果将模闆類全部放置在 .h 檔案裡面,那麼就不存在這個問題了。
模闆程式設計對于代碼重用确實有很大的實用性,不亞于繼承和封裝。
C++ Templates Tutorial http://www.iis.sinica.edu.tw/~kathy/vcstl/templates.htm
The declarations and definitions of the class template member functions should all be in the same header file.