Use static carefully: if you just want to write the function definition in the header file, use inline instead of static. Static and inline are different:
- Static functions are internal links. Different compilation units can have static functions with the same name, but this function is only visible to the corresponding compilation units. If the static function defined in the same definition is called by different compilation units, each compilation unit has its own copy, which is only visible to the corresponding compilation unit.
- The function of inline is external linkage. If it is called by different compilation units, each compilation unit references / links the same function and the same definition.
- The above differences directly lead to: if there is a static variable in the function, for the inline function, this variable is shared for different compilation units (Meyer's Singleton); for the static function, this variable is not shared. Look at the code below to see the difference.
There is no difference between the static inline function and the static function, so it is meaningless and only confusing.
The definition of the inline function does not have to be placed in a header file with the Declaration: the definition can be placed in a separate header file. hxx, in which the inline keyword needs to be added before the function definition. See point 2. Below for the reason; then the declaration is placed in another header file. hh, which includes the previous. hxx. This kind of use is very common in boost: 1. Implementation is separated from API, encapsulation. Advantages 2. It can solve the problem of loop call of inline function: if you don't expand, you can read this article: heads and includes: why and how Chapter 7, function inlining.
Specify inline
- Don't put inline and compiler optimization on the hook any more. Without inline, small function compilers will also optimize automatically. When you see inline, you should first think of other intentions, and then consider compiler optimization.
- The most useful use of inline is: non template function, member or non member. Put the definition in the header file without inline before the definition. If the header file is referenced by multiple cpp files, the compiler will report an error redefinition.
static_inline_A.h file:
#ifndef __STATIC_INLINE_A__ #define __STATIC_INLINE_A__ # include <iostream> namespace static_test { volatile static int a = 10; inline int& static_value() // (!*!) Or change this to inline { static int value = -1; return value; } namespace A { void set_value(int val); void print_value(); void set_static_value(int val); void print_static_value(); } } #endif // __STATIC_INLINE_A__
static_inline_A.cpp file:
# include "static_inline_A.h" namespace static_test { namespace A { void set_value(int val) { auto& value = static_value(); value = val; } void print_value() { std::cout << static_value() << '\n'; } void set_static_value(int val) { a = val; } void print_static_value() { std::cout << "A::a = " << a << std::endl; } } }
static_inline_B.h file:
#ifndef __STATIC_INLINE_B__ # define __STATIC_INLINE_B__ # include <iostream> namespace static_test { namespace B { void set_value(int val); void print_value(); void set_static_value(int val); void print_static_value(); }; } #endif // __STATIC_INLINE_B__
static_inline_B.cpp file:
# include "static_inline_A.h" # include "static_inline_B.h" namespace static_test { namespace B { void set_value(int val) { auto& value = static_value(); value = val; } void print_value() { std::cout << static_value() << '\n'; } void set_static_value(int val) { a = val; } void print_static_value() { std::cout << "B::a = " << a << std::endl; } } }
Test code:
# include "static_inline_A.h" # include "static_inline_B.h" int main() { static_test::A::set_value(42); static_test::A::print_value(); static_test::B::print_value(); static_test::B::set_value(37); static_test::A::print_value(); static_test::B::print_value(); static_test::A::set_static_value(100); static_test::A::print_static_value(); static_test::B::print_static_value(); static_test::B::set_static_value(200); static_test::A::print_static_value(); static_test::B::print_static_value(); system("pause"); return 0; }
Output:
Note: the same is true for defining static variables. Different static variables will be generated in different file references.