C++中的static关键字,全局作用域中的名字声明与定义
在C语言中,给全局作用域中的名字加上static关键字,表示这个名字只能在本文件内可见。而且C语言没有赋初值的全局变量在需要的时候被认为是声明而非定义,在连接器中,如果遇见多个强定义的名字,报重定义,如果遇见一个强定义,多个弱定义,则将强定义视为定义,弱定义当成声明,如果多个弱定义,则随机挑选一个作为定义,其他当成声明。
此外,C语言中函数是可以直接用而不声明的--连接器能在某个角落找到名字一致的带有定义的函数,因为C语言是不支持重载的,所以只要名字对了就可以,不会管参数对不对的。
这些在这里都有提到
因为C语言是底层语言,并且C被发明的时候作者并没有想到这些才会有这么多奇葩现象以及未定义行为,在C++中这些都会直接语法错误,所以在使用C++的过程,需要务必忘了C中的奇怪习惯,C和C++是两个完全不同的语言!!!!
在C++中,声明与定义区分得非常严格。
比如 int i;会一定被当成定义
const int i; 不会被当成声明,而是当成未给初始值的const int,所以报错
extern int i; 这就是个声明,不是定义,不分配内存,如果找不到定义,则报undefined的链接错误
extern int i = 2; 就是定义,在全局作用域中等价于 int i = 2;加上extern关键字是为了说明这个东西会再其他地方被引用,出现多次会报重定义。注意这里的出现多次,是指在全局作用域中出现多次,比如头文件中作死写个这,然后被多次包含,或者在多个源文件中写了extern int i;
所以可以保证不会报错的写法是:
1. 头文件someComm.h中声明,比如各种extern int x; extern const int sb;
2,一个源文件中定义,如someComm.cpp中定义extern int x = 213;
3, 其他源文件包含这个头文件之后链接到一起就不会出错了
然而即使这么做还是在作死,为什么C中要有static关键字,为什么C++中要由命名空间,都是为了避免全局命名空间污染。
so,正确的做法应该是:
1,头文件中定义一个命名空间,在命名空间中声明名字。
2,对应的源文件中using namespace sb;然后定义。
3,其他的地方包含头文件,用namespace::使用名字。
4,此外仅仅自己文件需要用的名字,放进未命名的命名空间中,反正别放全局命名空间就对了
然而即使这么做还是有不妥,全局变量的初始化顺序是不确定的,要使用全局函数返回这些值,同时这样还能避免这些奇怪的东西被当成内存泄露,影响检测工具的使用,不过以我的渣渣水平暂时不需要管这么多,先记下来以后填坑
浙公网安备 33010602011771号