天天看點

轉載:為什麼類模版的聲明和實作不能分開

今天實作了一個優先級隊列,經過調試,模版實作必須和聲明在同一個檔案中:

1 template<class T>
 2 class Priqueque
 3 {
 4     private:
 5         int maxSize;
 6         int n;
 7         T* queque;
 8         void Swap(int i,int j)
 9         {
10             T temp = queque[i];
11             queque[i] = queque[j];
12             queque[j] = temp;
13         }
14     public:
15         Priqueque(int maxSize);//³õʼ»¯ÓÅÏȼ¶¶ÓÁÐ
16         bool insert(T t);
17         T extractMin();
18 
19 };
20 template<class T> Priqueque<T>::Priqueque(int maxSize)
21 {
22     queque = new T[maxSize + 1];
23     this->maxSize = maxSize;
24     n = 0;
25 }
26 template<class T> bool Priqueque<T>::insert(T t)
27 {
28     if (n >= maxSize)
29     {
30         return false;
31     }
32     n++;
33     queque[n] = t;
34     for (int i = n,p = i/2;i > 1 && queque[i] < queque[p];i = p,p = i/2)
35     {
36         Swap(i,p);
37     }
38     return true;
39 }
40 template<class T> T Priqueque<T>::extractMin()
41 {
42     T ret_value = queque[1];
43     queque[1] = queque[n];
44     n--;
45     int i = 1;
46     int c = 2 * i;
47     while(c <= n)
48     {
49         if ((c + 1 <= n) && (queque[c+1] < queque[c]))
50         {
51             c++;
52         }
53         if (queque[i] < queque[c])
54         {
55             break;
56         }
57         Swap(i,c);
58         i = c;
59         c = 2 * i;
60     }
61     return ret_value;
62 }      

  對模版的這種實作方法提示幾點:

1. 模版的聲明和實作必須在同一個頭檔案中。原因後面分析

2. 實作中每個成員函數前都要加 template<class T>模版聲明,否則出現error C2065: 'T' : undeclared identifier類似錯誤

3. 實作函數前的模版類要将參數帶上,如 Priqueque<T>::

  那麼問題來了,為什麼模版類的實作不能分開寫呢?

  因為在編譯時模闆并不能生成真正的二進制代碼,而是在編譯調用模闆類或函數的CPP檔案時才會去找對應的模闆聲明和實作,在這種情況下編譯器是不知道實作模闆類或函數的CPP檔案的存在,是以它隻能找到模闆類或函數的聲明而找不到實作,而隻好建立一個符号寄希望于連結程式找位址。但模闆類或函數的實作并不能被編譯成二進制代碼,結果連結程式找不到位址隻好報錯了。

  這裡有篇好文章:http://www.cppblog.com/michaelgao/archive/2008/10/09/63571.html