C++ 语言特性24 - inline 和 static 关键字
一:inline 关键字
inline
主要用于函数的内联展开和解决多重定义问题。它的主要作用是建议编译器在调用处直接插入函数的代码,以减少函数调用的开销。编译器可以根据自己的优化策略选择是否实际进行内联。主要是用于建议编译器将函数调用内联展开,并且在多个翻译单元中定义函数时避免多重定义问题。
inline int add(int a, int b) {
return a + b;
}
add 函数可能在编译时直接被插入到调用点,而不是生成一个函数调用指令。
二:static 关键字
static
的含义和用法更广泛,它可以用于变量和函数,并且在不同上下文中作用不同。
1 用于局部变量
当 static
用于局部变量时,变量的生命周期是整个程序的运行期间,但它的作用域仍然局限于函数内。这种变量在第一次调用时被初始化,之后的每次调用都使用同一个变量值。
void example() {
static int counter = 0; // 局部静态变量
counter++;
std::cout << "Counter: " << counter << std::endl;
}
//这里的 counter 变量在程序的整个生命周期内都存在,但只有 example 函数能够访问它。
2 用于全局变量或函数
当 static
用于全局变量或函数时,它的作用是限制该变量或函数的作用域仅限当前的翻译单元。这意味着即使其他翻译单元中有相同名字的变量或函数,也不会产生冲突。
static int globalVar = 42; // 仅在当前文件可见
三:inline static 结合使用
当 inline
和 static
一起使用时,它们可以应用在不同的场景,特别是在函数和类的静态成员变量中。
1 inline
和 static
函数
inline static
函数:如果将一个函数同时标记为inline
和static
,则它具备两方面的特性:static
:该函数的作用域局限于当前翻译单元(通常是.cpp
文件),因此其他翻译单元无法看到该函数。inline
:编译器可以选择在调用点内联展开该函数,从而减少调用开销。
static inline int multiply(int a, int b) {
return a * b;
}
//在这个例子中,multiply 函数只在当前翻译单元中可见,并且编译器可以将它内联展开。
2 inline static
类成员变量
在 C++17 之前,静态成员变量的定义必须在类外部(通常在 .cpp
文件中)进行,即使它在类中声明过。而从 C++17 开始,引入了内联静态成员变量的概念,使得静态成员变量可以在类的内部直接初始化。
static
成员变量:静态成员变量属于类本身而不是某个对象的实例,它在所有类的实例中是共享的。inline
静态成员变量:从 C++17 开始,静态成员变量可以在类内部声明时就初始化,并且可以在多个翻译单元中定义而不产生链接冲突。
class MyClass {
public:
static inline int staticVar = 42; // C++17 引入的内联静态成员变量
};
//在这个例子中,staticVar 是一个静态成员变量,可以直接在类内部初始化,而不需要在类外部再次定义。
//为什么引入 inline static 成员变量?在 C++17 之前,静态成员变量的初始化必须在类外部提供定义:
// C++17 之前
class MyClass {
public:
static int staticVar;
};
// 必须在类外部定义
int MyClass::staticVar = 42;
//而在 C++17 引入 inline 之后,这种外部定义可以被省略,变量可以直接在类内部进行初始化。这减少了类外定义的额外步骤,简化了代码组织。