头文件中使用static变量

static是C/C++中让人迷惑的关键字。在一个文件对变量使用static关键字,则表示这个变量的作用范围仅限于本文件。
那么对于在头文件中使用static关键字,结果会如何呢。

首先,我们要明白,C++中对于头文件的处理。每个cpp文件在编译的时候都会将头文件(*.h)进行展开,这样就导致每个生成的*.o文件中均包含使用static修饰的变量,并且这个变量对其他文件不可见。结果是出现多份的变量,每个cpp文件中都只能访问本地的变量,这是一件较为危险的使用方法。

使用如下代码验证:

/*
    staticValue.hpp
    Check if static value will be copy in different .cpp s
*/
#pragma once

static int a = 0;
/*
    funcA.cpp
*/
#include <iostream>
#include "staticValue.hpp"

int funcA()
{
    std::cout<<"[funcA]"<<" &a\t= "<<&a<<std::endl;
    std::cout<<"[funcA]"<<" &::a\t= "<<&::a<<std::endl;
    return 0;
}
/*
    funcB.cpp
*/
#include <iostream>
#include "staticValue.hpp"

int funcB()
{
    std::cout<<"[funcB]"<<" &a\t= "<<&a<<std::endl;
    std::cout<<"[funcB]"<<" &::a\t= "<<&(::a)<<std::endl;
    return 0;
}
/*
    main.cpp
*/
#include <iostream>
#include "staticValue.hpp"

extern int funcA();
extern int funcB();

int main(void)
{
    std::cout<<"[main]"<<" &a:\t= "<<&a<<std::endl;
    std::cout<<"[main]"<<" &::a:\t= "<<&::a<<std::endl;
    funcA();
    funcB();
    return 0;
}

编译执行

[email protected]:~/$ g++ -g -o static-value main.cpp funcA.cpp funcB.cpp
[email protected]:~/$ ./static-value 
[main] &a:	= 0x602198
[main] &::a:	= 0x602198
[funcA] &a	= 0x6021a0
[funcA] &::a	= 0x6021a0
[funcB] &a	= 0x6021a8
[funcB] &::a	= 0x6021a8

发表评论