multiple definition of `xxxx`问题

纸上得来终觉浅,绝知此事要躬行。

昨天和同事在讨论一段c++代码的时候发现一个有意思的事情,简单来说问题是这样的, 现在有a.h, a.cpp, b.cpp

a.h

#ifndef _A_H
#define _A_H
...
...
#endif

a.cpp

#include "a.h"
...
...

b.cpp

#include "a.h"

int main()
{
...
}

现在有这么一个问题,需要一个全局变量,考虑到在a.cpp和b.cpp中都要使用,所以就把这个变量定义在a.h中,编译的时候

没有error, 但是在链接的时候抛出多重定义的错误,考虑到a.h已经加了#program once, 按理在整个工程中不会被重复编译,后来

搜索后发现,原来编译的时候是分离的,也就是说编译a.cpp和b.cpp时二者是不可见的,在预编译的时候把include里面的代码

拷到对应的cpp文件中,然后各自编译成.o文件,最后再将两个.o文件链接一起生成exe文件,而在各自编译.o文件的过程中,是

不知道外面的情况的,而一旦链接的时候就会发现原来外面也定义了这个变量,为此就会报错。

对于#program once的作用,其实只是为了保证该头文件只被拷贝一次到对应的cpp文件,而不是说保证整个工程值拷贝一次。

具体的场景是,如果a.h中有#include<iostream>, 而我在b.cpp中也有#incldue<iostream>, 那么在编译b.cpp的时候就会拷贝两

次iostream.所以我们可以看到iostrean中会有#program once,这样就可以避免在一个文件(而非工程)中被include两次。

解决方案:

对于这中问题的解决方案也很简单,因为我们在头文件中定义了变量,所以在不同cpp编译的时候都生成该变量,为了阻止这

种事情发生,只需要把定义改为声明,声明就是extern int a, 然后只在某一个cpp(任何一个CPP)中对其声明就可以啦。

思考:

当工程很简单的时候,上述的问题我们基本不会遇到,因为单个cpp完全没有问题,但是对于大型工程就要非常注意,而面对

这样的问题最重要的就是养成头文件不放定义的好习惯,所有的定义都放在具体的cpp中,头文件只负责声明。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值