【1】hpp文件
hpp,Header plus plus的縮寫,實質是將.cpp的實現代碼混入.h頭文件,即聲明與定義(實現)都包含在同一個文件中。
該類的調用者只需要include該hpp文件即可,無需再將cpp加入到project中進行編譯。
實現代碼將直接編譯到調用者的obj文件中,不再生成單獨的obj。
采用hpp將大幅度減小project中的cpp文件數與編譯次數,也不再發布煩人的lib與dll,因此非常適合用來編寫公用的開源庫。
hpp文件與h文件的聯系:
(1)與*.h類似,hpp是C++程序的頭文件
(2)是VCL(Visual Component Library的縮寫,即可視組件庫)專用的頭文件,已預編譯
(3)是一般模板類的頭文件
(4)一般來說,*.h里面只有聲明,沒有實現;而*.hpp里面既有聲明也有實現,顯然后者可以減小cpp的數量。
【2】hpp文件應用示例
典型應用示例:模板類
(1)分開模板類的聲明與定義
1.1 新建.h頭文件
1 //pair.h文件 2 3 #pragma once 4 5 template <class T1, class T2> 6 class Pair 7 { 8 public: 9 T1 key; // 關鍵字 10 T2 value; // 值 11 12 public: 13 Pair(T1 k, T2 v); 14 bool operator < (const Pair<T1, T2>& p) const; 15 };
1.2 新建.cpp實現文件
1 // pair.cpp 2 3 #include "pair.h" 4 5 template<class T1, class T2> 6 Pair<T1, T2>::Pair(T1 k, T2 v) : key(k), value(v) 7 {} 8 9 template<class T1, class T2> 10 bool Pair<T1, T2>::operator < (const Pair<T1, T2>& p) const 11 { 12 return key < p.key; 13 }
1.3 新建main.cpp調用文件
1 // main.cpp文件 2 3 #include <iostream> 4 #include <string> 5 6 #include "pair.h" 7 8 int main() 9 { 10 Pair<std::string, int> student("kaizenly", 19); //實例化出一個類 Pair<std::string, int> 11 std::cout << "key: " << student.key << " " << "value: " << student.value; 12 return 0; 13 }
構建結果:鏈接錯誤,如下圖:
分析原因:
a 編譯能通過
參與編譯的只是.cpp文件,因為它能在.h里面找到模板的聲明,所以編譯正常。
b 鏈接錯誤
<1> 鏈接時,先需要實例化模板,即先找模板的具體實現。
如上,在main函數中調用了一個模板類對象(T1為std::string, T2為int),這時候就需要去實例化該類型的模板。
注意,在main函數里面只包含了.h文件,也就是只有模板的聲明,沒有具體實例(T1為std::string, T2為int)的實現。因此就會報錯。
<2> 模板實現在.cpp里面,雖然有模板具體實現,但是沒有具體誰(T1為std::string, T2為int)在該.cpp里面使用一個模板類,也就不會生成一個具體化的實例。
ps:模板是在需要的時候,才會去生成一個具體化的實例。比如:
當你只要一個(T1為std::string, T2為int)型的實例,模板就只會給你生成一個(T1為std::string, T2為int)型的實例。
模板本身是不會被執行的(也就是模板本身不產生匯編指令),是模板生成的具體化實例才產生指令(這個實例是隱藏的,我們是看不到的)。
(2)模板類聲明與定義寫在一起
1.1 新建.hpp頭文件(將模板類的聲明和定義寫在一起)
1 // pair.hpp文件 2 3 #pragma once 4 5 template <class T1, class T2> 6 class Pair 7 { 8 public: 9 T1 key; // 關鍵字 10 T2 value; // 值 11 12 public: 13 Pair(T1 k, T2 v); 14 bool operator < (const Pair<T1, T2>& p) const; 15 }; 16 17 template<class T1, class T2> 18 Pair<T1, T2>::Pair(T1 k, T2 v) : key(k), value(v) 19 {} 20 21 template<class T1, class T2> 22 bool Pair<T1, T2>::operator < (const Pair<T1, T2>& p) const 23 { 24 return key < p.key; 25 }
1.2 新建main.cpp文件
1 // main.cpp文件 2 3 #include <iostream> 4 #include <string> 5 6 #include "pair.hpp" 7 8 int main() 9 { 10 Pair<std::string, int> student("kaizenly", 19); //實例化出一個類 Pair<std::string, int> 11 std::cout << "key: " << student.key << " " << "value: " << student.value; 12 return 0; 13 }
1.3 編譯、鏈接正常:
good good study, day day up.
順序 選擇 循環 總結