C++ 静态成员变量文件作用域

C++ 静态成员变量文件作用域,c++,C++,静态变量的作用域仅在声明它们的文件中,如下代码所示: 文件1- static int a; 文件2- extern int a; #include "file1" extern int a; 这将导致链接错误,因为静态变量a的作用域仅在file1中。但我对以下代码感到困惑: 文件2- extern int a; #include "file1" extern int a; 在这里,它不会给出任何链接错误。这就意味着编译器引用了文件1中声明的“a”。但当您调试时,您会发现变量“a”的地址

静态变量的作用域仅在声明它们的文件中,如下代码所示:

文件1-

static int a;
文件2-

extern int a;
#include "file1"
extern int a;
这将导致链接错误,因为静态变量a的作用域仅在file1中。但我对以下代码感到困惑:

文件2-

extern int a;
#include "file1"
extern int a;
在这里,它不会给出任何链接错误。这就意味着编译器引用了文件1中声明的“a”。但当您调试时,您会发现变量“a”的地址在file1和file2中不同。编译器是否正在文件2中创建另一个全局变量“a”

完整代码-

文件temp1.h-

static int w = 9;

class temp1 
{
public:
   temp1(void);
public:
   ~temp1(void);

   void func();

};
cpp

temp1::temp1(void)
{
   int e =w;
}

temp1::~temp1(void)
{
}
void temp1::func()
{
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 文件2-


在这里,当我调试和检查temp1构造函数和file2中的值和adress时,它们是不同的。

static
extern
与文件无关,它们与转换单元有关。请记住,当您包含某个内容时,预处理器实际上是在进行复制和粘贴<代码>静态等。指的是该过程的结果,它是一个翻译单元

在第二个例子中,只有一个翻译单元。因此只有一个变量
a
。[但请注意,这样做被认为是非常糟糕的风格。]

file1:

static int a;
文件2:

extern int a;
这里引用了两个变量。第一个是
file1
中具有内部链接的变量的声明和定义;第二个是在
file2
中仅声明具有外部链接的变量。这不一定会导致错误;在某些翻译单元中使用具有外部链接的变量,在其他翻译单元中使用具有内部链接的同名变量是完全合法的。只有在
file2
中使用了
a
并且
file2
或程序中的任何其他翻译单元中没有此
a
的定义时,才会发生任何链接错误

#include "file1"
extern int a;
在本例中,您已将两个文件合并为一个翻译单元。变量
a
首先在
文件
中声明和定义,由于
静态
,它具有内部链接,第二个只是重新声明,不会改变以前的链接。在本例中,第二个声明是多余的。如果您仍在分别编译这两个文件,并包含来自
file2
file1
,则每个翻译单元(
file1
file1+file2
)都将有其自己独特的变量,称为
a


注意,如果您使用了
extern inta后接
静态int a
则这将是一个编译错误,因为如果以前没有可见的声明,则第一个声明将声明
a
具有外部链接,然后第二个声明和定义将导致错误,因为
静态int a所隐含的链接将与前面的声明冲突。

是,这是一个翻译单元。但为什么两个文件中的varaibale“a”的地址不同?@Ghanshyam:我认为您必须编辑您的问题,以显示一个完整的、可编译的示例来说明您的意思。@Ghanshyam:这与变量的地址无关。请用一些代码编辑您的原始问题!除非
temp1.h
包含自身,否则该代码不完整(或可能不正确)。你能展示一下temp1.h的内容吗?编辑后,我想我的答案完全回答了你的问题。在两个翻译单元中,
w
具有内部链接,因为
w
的第一个声明是
静态int w=9头文件中包含的声明。这意味着两个翻译单元都有各自独立的
w
。因此,这意味着第二个翻译单元也定义了变量w,即使它是外部的(因为它不会导致重新定义,因为第一个定义是翻译单元1中的内部链接)?是,没有初始值设定项的标记为
extern
的对象声明永远不是定义。如果对象之前已声明,则链接取自先前的声明(在本例中为内部声明),如果不存在先前的声明,则对象具有外部链接。两个翻译单元中唯一的定义来自头文件中的
静态
声明。感谢查尔斯的澄清。