You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多文件编译下static变量地址与this不一致问题咨询

关于static全局变量的两个疑问

我在测试中编写了以下代码:

Foo.h代码

struct Foo {
    Foo();
    void dummy(){}
};
static Foo foo;

Foo.cpp代码

#include "Foo.h"
#include <iostream>
Foo::Foo()  {
    std::cout<<&foo<<std::endl;
    std::cout<<this<<std::endl;
};

main.cpp代码

#include "Foo.h" // 注:原代码写为#include "a.h",应为笔误
int main(){
    foo.dummy();
}

运行后输出:

0x7f333ff1077e
0x7f333ff1077e
0x7f333ff1077e
0x7f333ff1077c

疑问:

  • 为何会出现两个不同的地址?实际是创建了两个static变量吗?
  • 为何构造函数中&foo和this的地址会不一致?

另外,如果把所有代码合并到单个头文件中,输出符合预期:

0x7f385b59973f
0x7f385b59973f

问题解答

  1. 确实创建了两个独立的static变量
    C++里,static修饰的全局变量作用域仅限于当前编译单元。当头文件被多个编译单元(Foo.cpp和main.cpp)包含时,每个编译单元都会独立生成一份static Foo foo的实例。所以这里实际存在两个完全独立的foo对象,分别归属Foo.cpp和main.cpp两个编译单元。

  2. &foo与this地址不一致的原因
    构造函数Foo::Foo()是全局可见的函数,但函数内的foo会解析为Foo.cpp编译单元里的static变量(因为构造函数定义在Foo.cpp中)。

  • 当Foo.cpp中的foo构造时,&foo和this都指向这个实例,所以前两行地址相同;
  • 当main.cpp中的foo构造时,调用的是同一个构造函数,此时&foo仍然指向Foo.cpp里的foo,但this指向的是正在构造的main.cpp里的foo,因此出现了地址不一致的情况(第三行是Foo.cpp的foo地址,第四行是main.cpp的foo地址)。

合并到头文件的情况

当所有代码放在单个头文件时,整个程序只会生成一个编译单元,因此只会创建一个static Foo foo实例。构造函数执行时,&foo和this指向同一个对象,所以输出的地址完全相同。


内容的提问来源于stack exchange,提问作者cppBeginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:01:03