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.
顺序 选择 循环 总结