C++ 静态成员变量文件作用域
静态变量的作用域仅在声明它们的文件中,如下代码所示: 文件1-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”的地址
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
的对象声明永远不是定义。如果对象之前已声明,则链接取自先前的声明(在本例中为内部声明),如果不存在先前的声明,则对象具有外部链接。两个翻译单元中唯一的定义来自头文件中的静态
声明。感谢查尔斯的澄清。