当前位置:   article > 正文

总结C++重定义问题(multiple definition)_c++ multiple definition

c++ multiple definition

我们都知道变量或者函数在一个项目中可以存在多次声明,但定义只能出现一次,如果出现多次,编译或链接时就会报multiple definition问题。下面就该问题简要探讨一下:

DEMO

  1. // f.h
  2. int a = 1;
  3. // g.h
  4. #include "f.h"
  5. // main.cpp
  6. #include "f.h"
  7. #include "g.h"
  8. int main()
  9. {
  10. }

编译

  1. > g++ -o main main.cpp
  2. In file included from g.h:1:0,
  3. from main.cpp:2:
  4. f.h:1:5: error: redefinition of ‘int a’
  5. int a = 1;
  6. ^
  7. In file included from main.cpp:1:0:
  8. f.h:1:5: note: ‘int a’ previously defined here
  9. int a = 1;

解释

main.cpp重复包含头文件f.h,等于定义两次变量a。

解决

头文件中加上宏保护#ifndef ...或者#pragma once,保证头文件在一个cpp文件编译过程中只会被包含一次

  1. // 修改后的f.h
  2. #ifndef F_H_
  3. #define F_H_
  4. int a = 1;
  5. #endif

思考

头文件加上宏保护就一定能防止重定义了吗?显然不能,如

  1. // f.h
  2. #ifndef F_H_
  3. #define F_H_
  4. int a; // 不加extern关键字,就是定义
  5. #endif
  6. // f.cpp
  7. #include "f.h"
  8. // main.cpp
  9. #include "f.h"
  10. int main()
  11. {
  12. }

编译

  1. > g++ -o main main.cpp f.cpp
  2. /usr/bin/ld: /tmp/ccjDbdBf.o:(.data+0x0): multiple definition of `a'; /tmp/cc50XAei.o:(.data+0x0): first defined here
  3. collect2: error: ld returned 1 exit status

解释

宏保护只能保证头文件在一个cpp文件编程过程中不被重复包含,因此编译生成main.o,f.o是没有问题的,但是链接时发现main.o,f.o中都存在变量a的定义。

解决

不要在头文件中定义变量或函数。

  1. // 修改后的f.h
  2. #ifndef F_H_
  3. #define F_H_
  4. extern int a;
  5. #endif
  6. // 修改后的f.cpp
  7. #include "f.h"
  8. int a = 1;

注意这里说的是变量,如果头文件定义的是常量如const int a = 1;,被不同cpp包含时,编译和链接时不会报错。原因见C++ primer中的一段话

const int bufSize = 1024; // 缓冲区大小,编译器将在编译过程中把变量bufSize都替换成1024。
为了执行上述替换, 编译器必须知道变量的初始值。如果程序包含多个文件, 则每个用了const对象的文件都必须能访问到它的初始值才行。要做到这一点, 就必须在每一个用到变量的文件中都有对它的定义。为了支持这一用法, 同时避免对同一变量的重复定义, 默认情况下, const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时, 其实等同于在不同文件中分别定义了独立的变量。

拓展

做到以上两点基本能解决平时80%的重定义问题,那还有20%呢?

1. 两个cpp文件中定义了相同的全局变量

解决:a)换个名字,简单直接。b)如果不愿改名,那就至少要在其中一个变量定义前加上static或者const修饰。

解释:static修饰的变量或者函数只在当前编译单元内可见,不会与那些全局可见性的同名变量冲突。

还有其它场景欢迎补充。。。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/838266
推荐阅读
相关标签
  

闽ICP备14008679号