本文介绍: 1. 对外声明函数必需加上inline, 消除连接的歧义2. 在inline 函数内部声明的static 对象, 在多个文件包含时,对象唯一

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 文件中,怎样避免函数重复定义

这里写了一个简单测试用例,搞清楚了这两个问题代码copy 下来编译可以通过的.

$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 %dn”,_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.cppother_file.cpp 中都包含这个header_only.h, 都来调用obj->print_it(), 发现这是同一个obj
代码如下:

$cat main.cpp 
#includeheader_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
 

小结:
是的,问题是解决了,问题到底是谁解决的? 你可以说是自己,但其实真正的问题解决者是gcc.
当你在头文件中声明inline 函数时, gcc 就会试图在本地展开函数代码, 如果它不方便展开,也会分解为多次调用,一次实现的方式. 以便满足函数不重复定义的要求.
这不就是我们费半天一天不见得把复杂的header_only文件拆分成.h和.cpp文件的工作
gcc 瞬间就帮我们搞定了. 你在inline 函数内声明的static 变量,由于其只有一处实现,所以就是唯一的了.
所以说,牛X的是gcc ,我们只是牵了一下牛鼻子而已!

原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/134672054

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_33988.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注