C++ 无法理解静态行为
我写了一封信C++ 无法理解静态行为,c++,c,C++,C,我写了一封信 // In file t.h #ifndef __t_h__ #define __t_h__ static int abc; #endif -- //在main.c中 #包括 #包括“t.h” int main() { abc++;printf(“%d\n”,abc); test(); } -- //在test.c中 #包括 #包括“t.h” 无效测试() { abc++; printf(“%d\n”,abc); } 当我运行项目时,我发现abc的输出是1和1。 但是当我在
// In file t.h
#ifndef __t_h__
#define __t_h__
static int abc;
#endif
--
//在main.c中
#包括
#包括“t.h”
int main()
{
abc++;printf(“%d\n”,abc);
test();
}
--
//在test.c中
#包括
#包括“t.h”
无效测试()
{
abc++;
printf(“%d\n”,abc);
}
当我运行项目时,我发现abc的输出是1和1。
但是当我在t.h
中将其更改为intabc
时。abc=1和2的输出。
为什么static在控件到达test.c
文件时不保留该值。
如果它不保留,那么为什么不提供一个错误,因为静态变量不能在文件之间共享?静态变量具有内部链接,这意味着每个翻译单元都有自己的副本
因此,在您的程序中,每个包含t.h
的.cpp
文件都有自己的静态变量副本,这意味着内存中有两个对象。您可以尝试打印他们的地址以确认这一点,因为他们会有所不同
这使情况变得非常简单:如果在一个.cpp
文件中更改对象,它不会反映在另一个.cpp
文件中,因为另一个.cpp
文件中的对象是不同的对象。为什么要改变呢
但当您将其更改为intabc
(即不要使其为静态的
)时,每个翻译单元都有相同的对象。如果您在一个文件中更改它,它也将反映在另一个文件中,正如预期的那样
至于共享,那么是的,静态
对象可以在同一翻译单元中的两个函数之间共享,但不能在两个翻译单元之间共享
在这个网站上搜索翻译单元,你会得到很多关于它的主题。阅读它们,您将完全理解。当您在头文件中声明一个静态变量时,将在包含头文件的每个中创建静态变量的副本。因此,您的程序中涉及的每个翻译单元现在都有自己的abc
副本,因此您可以得到观察到的行为。该行为不是您期望的,而是定义良好的行为
静态
变量不能在文件之间共享?
不,他们不可能!这正是使它们静态
静态
变量具有。它们的范围仅限于声明它们的翻译单位。它们不能在TU之外访问。如果要在不同的翻译单元之间共享同一变量,则应删除静态
,并使用外部
,从而使变量具有外部链接,从而在不同的翻译单元之间可见
读得好:
当预处理器处理完代码后,main.c看起来像
// omitted stuff from stdio
static int abc;
int main()
{
abc++;printf("%d \n", abc);
test();
}
// omitted stuff from stdio
static int abc;
void test()
{
abc++;
printf("%d \n", abc);
}
test.c看起来像
// omitted stuff from stdio
static int abc;
int main()
{
abc++;printf("%d \n", abc);
test();
}
// omitted stuff from stdio
static int abc;
void test()
{
abc++;
printf("%d \n", abc);
}
因此,每个文件都包含自己的变量abc
,无法从另一个文件访问
一种解决方案是将t.h改为
#ifndef __t_h__
#define __t_h__
extern int abc;
#endif
然后将main.c改为
#include <stdio.h>
#include "t.h"
int abc;
int main()
{
abc++;printf("%d \n", abc);
test();
}
#包括
#包括“t.h”
国际广播公司;
int main()
{
abc++;printf(“%d\n”,abc);
test();
}
您可以这样想:现在在main.c中,您的程序中只有一个int abc
,但是test.c知道它的存在,因为extern int abc
告诉test.c在项目的其他地方有一个名为abc
的整数,它可以在链接时找到它 在C中,静态
有两种用法:
1、使用static
关键字限制var在转换单元中的范围。为了简单起见,如果您有两个文件:a.c
,b.c
,并且您编写了:
static int varA;
static void StaticFunction();
在a.c
中,这意味着varA
只能在a.c
中使用,如果你想在b.c
中使用varA
,你应该删除静态
关键字,并添加extern int varA
在b.c
中,人们通常做的是创建另一个名为:a.h
的文件,并编写extern int varA
在a.h
中,我们只需在b.c
中包含“a.h”
,这样我们就可以在a.h
中写入我们想要外部的每个变量,并使用单个包含“a.h”
使这些变量或函数在其他.c
文件(即源文件)中合法
2、使用static
在函数中定义局部变量
,例如:
int TheFunction()
{
static int var = 0;
return ++var;
}
由于您对局部变量var
使用了static
关键字,因此在返回function()
时,此变量不会丢失
第一次调用TheFunction()
会得到1
,第二次调用TheFunction()
会得到2
,依此类推
<强>下,让我们看看C++中的静态用法。< /强>
因为任何C++编译器都能兼容C代码,所以上面的2个用法也在C++中。
另外两种用法是:
1、静态成员变量。
2、静态成员函数
让我们直接查看代码:
#include <iostream>
using namespace std;
class Test
{
public:
Test() : m_nNormalVar(0)
{
}
public:
// You need to init this static var outside the class
// using the scope operator:
// int Test::m_nStaticVar = 0;
static int m_nStaticVar;
// You can init this const static var in the class.
const static int m_nConstStaticVar = 10;
// This is just a normal member var
int m_nNormalVar;
};
int Test::m_nStaticVar = 0;
int main(int argc, char *argv[])
{
Test a;
Test b;
a.m_nStaticVar++;
a.m_nNormalVar++;
cout << b.m_nStaticVar << endl;
cout << b.m_nNormalVar << endl;
return 0;
}
这是C++中类的静态成员函数。
我只知道静态的这四种用法,如果还有其他用法,请帮助编辑这篇文章,thx:)
编辑:
添加静态全局函数
1、使用static
关键字限制功能在翻译单元中的范围。为了简单起见,如果您有两个文件:a.c
,b.c
,并且您编写了:
static int varA;
static void StaticFunction();
在a.c
中,因此只能在a.c
中调用StaticFunction()
,如果要在b.c
中调用此函数,应删除static
关键字,然后删除delca