c/c++ header_only 头文件实现的关键点
header_only 头文件实现的关键点
-------------------------------------------------------------------------
author: hjjdebug
date: 2023年 11月 28日 星期二 16:58:38 CST
descriptor: header_only 头文件实现的关键点
1. 对外声明的函数必需加上inline, 消除连接的歧义
2. 在inline 函数内部声明的static 对象, 在多个文件包含时,对象是唯一的
-------------------------------------------------------------------------
看到一个loger 文件,它只有头文件,变量,代码的实现都在一个头文件中, 那它是如何解决下面2个问题的.
问题1: 在多个文件中包含一个header_only 头文件, 里面如果有定义变量, 它肯定应该是一个, 那它是怎么做到的?
问题2:在多个文件中包含一个header_only 头文件, 把函数体写在.h 文件中,怎样避免函数重复定义?
我这里写了一个简单的测试用例,搞清楚了这两个问题。
cat header_only.h
#ifndef _HEAD_ONLY_H
#define _HEAD_ONLY_H
#include <stdio.h>
class _MY_OBJ
{
public:
_MY_OBJ(){_hide = 0;}
void setData(int d){_hide = d;}
void print_it(){printf("data is %d\n",_hide);}
private:
int _hide;
};
//一般做法行不通,有2个问题
//static _MY_OBJ s_obj; 在全局变量位置声明的static 变量, 每包含一次会生成一个全局的对象, 必需修改!
//_MY_OBJ *getDefaultObj(){return &s_obj;} //有multiple definition of `getDefaultObj()' 连接有问题,必需修改!
//
//1. 必需加上inline, 消除连接问题 多重函数定义
inline _MY_OBJ *getDefaultObj()
{
static _MY_OBJ s_obj; //2. 在inline 函数内部声明的static 对象, 在多个文件包含时,对象是唯一的
return &s_obj;
}
//所以header_only 头文件的关键是2点
//1. 必需加上inline, 消除连接问题 多重函数定义
//2. 在inline 函数内部声明的static 对象, 在多个文件包含时,对象是唯一的
#endif
我们在main.cpp 和 other_file.cpp 中都包含这个header_only.h, 都来调用obj->print_it(), 发现这是同一个obj
代码如下:
$cat main.cpp
#include "header_only.h"
#include "other_file.h"
int main()
{
_MY_OBJ *obj = getDefaultObj(); // main 函数中得到一个obj
obj->setData(3);
obj->print_it();
other_print(); // other_file 中也会得到一个obj, 但它们是同一个obj
return 0;
}
$cat other_file.h
#ifndef _OTHER_FILE_H
#define _OTHER_FILE_H
void other_print();
#endif
$ cat other_file.cpp
#include "other_file.h"
#include "header_only.h"
void other_print()
{
_MY_OBJ *obj=getDefaultObj();
printf("in other file print.\n");
obj->print_it();
}
该函数的执行结果:
$ ./head_only
data is 3
in other file print.
data is 3
从运行结果上可以看出, main中得到的obj与other_file中得到的obj是同一个obj