C++:重定义:符号重定义:变量重定义_hongwen_yul的博客-CSDN博客
上一篇文章中,我们知道解决变量重复定义其中一个办法是:尽量不要头文件中定义变量,头文件只做变量的声明。但是如果我们一定要在头文件中定义,那应该怎么处理了 ?
1:将变量定义成const
a.h
#pragma once
const int A = 2;
=====================================================================================
b.h / b.cpp 代码保持不变,并且按照正常编译指令编译成 b.o 即:
gcc -c b.cpp -o b.o
====================================================================================
c.h/c.cpp 代码也保持不变, 按照正常编译指令编译成 c.o 即:
gcc -c c.cpp -o c.o
====================================================================================
main.cpp 代码保持不变,按照正常编译指令编译成 main.o 即:
gcc -c mian.cpp -o main.o
==================================================================================
链接: 我们使用指令将 b.o / c.o/ mian.o 三个文件链接起来 即:
gcc b.o c.o main.o -o main.exe
发现并没有报错,可以正常运行,并可以正常打印出相关数值。
为什么变量用 const 修饰后,就不报错了 ?
- 为全局的 const对象默认没有 extern声明,所以在只在当前文件有效,把这样的对象写在头文件中, 即使它后来被其他多个 .cpp 文件包含进去,那么这个对象也只在包含它的那个文件中有效, 对其他文件来说是不可见的,所以 便不会出现多重定义的情况 。
- 同时,这些 .cpp 文件中的该对象都是从一个头文件中包含进去的,这样也可以保证 这些 .cpp 文件中的这个 const对象的值是相同的,可谓一举两得。
2:将变量定义成static
在 C 语言中,对于被声明为 static 的全局实体(包括变量和函数),在声明它的文件之外是不可见的。这句话来自于C++ Primer一书,如下所示:
- 在C语言编程中,static的一个作用就是信息屏蔽。比方说,你自己定义了一个文件,该文件中有一系列的函数以及变量的声明和定义,你希望该文件中的一些函数和变量只能被该文件中的函数使用,那么,你可以在该函数、变量的前面加上static,代表他们只能被当前文件中的函数使用,在其他文件中不能调用,即使在其他文件中声明这个函数都没用。
- 所以,在不同文件中定义同名的staitc函数是没问题的,不会冲突的。
- 对于本例中,如果在变量和函数前添加一个static修饰,就不会再提示变量重复定义的问题。因为static限定的变量和函数只在包含头文件的cpp中是可见的,在其他cpp中不可见,所以多个cpp包含这个头文件多次去定义变量和函数,因为相互之间不可见,所以没有出现重复定义的问题。
那既然有了上面的理论依据,我们可以将 a.h 头文件里面的变量 A定义成 static
a.h
#pragma once
static int A = 2;
=====================================================================================
b.h / b.cpp 代码保持不变,并且按照正常编译指令编译成 b.o 即:
gcc -c b.cpp -o b.o
====================================================================================
c.h/c.cpp 代码也保持不变, 按照正常编译指令编译成 c.o 即:
gcc -c c.cpp -o c.o
====================================================================================
main.cpp 代码保持不变,按照正常编译指令编译成 main.o 即:
gcc -c mian.cpp -o main.o
==================================================================================
链接: 我们使用指令将 b.o / c.o/ mian.o 三个文件链接起来 即:
gcc b.o c.o main.o -o main.exe
发现并没有报错,可以正常运行,并可以正常打印出相关数值。
参考文献