C++ hpp文件


【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.

順序 選擇 循環 總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM