• C++:重定义:符号重定义:变量重定义(二):解决变量重定义


    C++:重定义:符号重定义:变量重定义_hongwen_yul的博客-CSDN博客

    上一篇文章中,我们知道解决变量重复定义其中一个办法是:尽量不要头文件中定义变量,头文件只做变量的声明。但是如果我们一定要在头文件中定义,那应该怎么处理了 ?

    1:将变量定义成const

    1. a.h
    2. #pragma once
    3. const int A = 2;
    4. =====================================================================================
    5. b.h / b.cpp 代码保持不变,并且按照正常编译指令编译成 b.o 即:
    6. gcc -c b.cpp -o b.o
    7. ====================================================================================
    8. c.h/c.cpp 代码也保持不变, 按照正常编译指令编译成 c.o 即:
    9. gcc -c c.cpp -o c.o
    10. ====================================================================================
    11. main.cpp 代码保持不变,按照正常编译指令编译成 main.o 即:
    12. gcc -c mian.cpp -o main.o
    13. ==================================================================================
    14. 链接: 我们使用指令将 b.o / c.o/ mian.o 三个文件链接起来 即:
    15. gcc b.o c.o main.o -o main.exe
    16. 发现并没有报错,可以正常运行,并可以正常打印出相关数值。

    为什么变量用 const 修饰后,就不报错了 ?

    • 为全局的 const对象默认没有 extern声明,所以在只在当前文件有效,把这样的对象写在头文件中, 即使它后来被其他多个 .cpp 文件包含进去,那么这个对象也只在包含它的那个文件中有效, 对其他文件来说是不可见的,所以 便不会出现多重定义的情况
    • 同时,这些 .cpp 文件中的该对象都是从一个头文件中包含进去的,这样也可以保证 这些 .cpp 文件中的这个 const对象的值是相同的,可谓一举两得。

    2:将变量定义成static

    在 C 语言中,对于被声明为 static 的全局实体(包括变量和函数),在声明它的文件之外是不可见的。这句话来自于C++ Primer一书,如下所示:

    1. 在C语言编程中,static的一个作用就是信息屏蔽。比方说,你自己定义了一个文件,该文件中有一系列的函数以及变量的声明和定义,你希望该文件中的一些函数和变量只能被该文件中的函数使用,那么,你可以在该函数、变量的前面加上static,代表他们只能被当前文件中的函数使用,在其他文件中不能调用,即使在其他文件中声明这个函数都没用。
    2. 所以,在不同文件中定义同名的staitc函数是没问题的,不会冲突的。
    3.        对于本例中,如果在变量和函数前添加一个static修饰,就不会再提示变量重复定义的问题。因为static限定的变量和函数只在包含头文件的cpp中是可见的,在其他cpp中不可见,所以多个cpp包含这个头文件多次去定义变量和函数,因为相互之间不可见,所以没有出现重复定义的问题。

    那既然有了上面的理论依据,我们可以将 a.h 头文件里面的变量 A定义成 static

    1. a.h
    2. #pragma once
    3. static int A = 2;
    4. =====================================================================================
    5. b.h / b.cpp 代码保持不变,并且按照正常编译指令编译成 b.o 即:
    6. gcc -c b.cpp -o b.o
    7. ====================================================================================
    8. c.h/c.cpp 代码也保持不变, 按照正常编译指令编译成 c.o 即:
    9. gcc -c c.cpp -o c.o
    10. ====================================================================================
    11. main.cpp 代码保持不变,按照正常编译指令编译成 main.o 即:
    12. gcc -c mian.cpp -o main.o
    13. ==================================================================================
    14. 链接: 我们使用指令将 b.o / c.o/ mian.o 三个文件链接起来 即:
    15. gcc b.o c.o main.o -o main.exe
    16. 发现并没有报错,可以正常运行,并可以正常打印出相关数值。

    参考文献

    一文带你彻底搞懂C/C++编程中static与extern两关键字的使用_dvlinker的博客-CSDN博客

  • 相关阅读:
    ArrayList分析2 :Itr、ListIterator以及SubList中的坑
    1361:产生数(Produce)
    疯狂Spring Boot讲义[推荐1]
    2021-06-09 51单片机:两个独立按键控制一个led,k1按下松开led闪烁三次,k2按下LED闪烁五次
    使用 NSProxy 实现消息转发
    MongoDB - 入门指南
    第一章 软件开发入门引导及概述
    把Android手机变成电脑摄像头
    MySQL之数据库管理(用户和数据权限管理)
    【Android Camera开发】Android Automotive介绍
  • 原文地址:https://blog.csdn.net/u013620306/article/details/127876249