前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Modern CPP]内联变量——保证变量唯一性的利器

[Modern CPP]内联变量——保证变量唯一性的利器

作者头像
程序员的园
发布2024-07-18 13:28:02
680
发布2024-07-18 13:28:02
举报
文章被收录于专栏:程序员的园——原创文章

在 C++ 中,一个定义了全局变量的头文件被多个源文件包含时,每个源文件都会创建该全局变量的一个实例,这可能导致链接时出现重定义错误,代码示例如下。

代码语言:javascript
复制
// example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H

int globalVar = 42;

#endif // EXAMPLE_H


// file1.cpp
#include "example.h"
// Some code using globalVar


// file2.cpp
#include "example.h"
// Some other code using globalVar

头文件中的变量globalVar会在file1.cpp和file2.cpp中分别创建实例,出现重定义的链接错误,MSVC的错误为LNK2005和LNK1169。

这是小编遇到的实际问题,在封装spdlog时,为了在宏内使用封装的对象,定义了全局变量,由于该日志类头文件被多个文件包含出现了链接错误。简化后的代码如下:

代码语言:javascript
复制
//log.h
Log logger;
// Define macros for different log levels
#define LOG_DEBUG(msg) logger.Log(LogLevel::Debug,__FUNCTION__,__LINE__, msg)

为了解决全局变量的重定义问题,C++17引入了内联变量的概念。

内联变量

使用 inline 关键字可以将变量声明为内联变量,在多个源文件中包含该头文件时,编译器只会创建一个该变量的实例。

如上实例中定义的全局变量globalVar可以修改为内敛变量,如下

代码语言:javascript
复制
// example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H

inline int globalVar = 42;

#endif // EXAMPLE_H

使用场景

1. 头文件中定义全局变量,保证变量定义的唯一性

代码语言:javascript
复制
// constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_H

inline constexpr double PI = 3.14159265358979323846;
inline constexpr std::string AppName = "MyApp";
#endif // CONSTANTS_H

2. 类的静态成员变量

可以用来定义模板类的内联静态成员变量,也可以用来定义普通类的内联静态成员,只是普通类的静态成员变量通常来讲定义在源文件内,没必要内联。

代码语言:javascript
复制
// template_class.h
#ifndef TEMPLATE_CLASS_H
#define TEMPLATE_CLASS_H

template<typename T>
class MyClass {
public:
    static inline T defaultValue = T();
};

#endif // TEMPLATE_CLASS_H

注意事项

内联变量有诸多的便利性,但是使用时仍需注意以下几点:

  • 必须在定义处进行初始化:内联变量的初始化必须在声明处完成。
  • 不要在多个源文件中定义相同的内联变量:虽然编译器只会保留一个实例,但仍然不建议在多个源文件中定义相同的内联变量,以避免混乱和不必要的复杂性。
  • 不要过度使用内联变量,每个编译单元都会维护一个内联变量的副本,如果定义过多的内联变量,不仅会导致程序占用大量的内存空间,也会增加编译时间。

总结

内联变量是 C++17 新增的特性,用于解决头文件中变量多实例化的问题。通过使用inline将变量声明为内联变量,可以确保在多个源文件中只有一个变量实例,避免了链接时的重定义错误。然而,仍需要谨慎使用内联变量,并注意其初始化和定义的位置,以确保程序的正确性和可维护性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档