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.

顺序 选择 循环 总结

posted @ 2020-04-12 21:05  kaizenly  阅读(12291)  评论(0编辑  收藏  举报
打赏