错题集
May God Bless You

在编译是有时会遇到:

error : multiple definition of "foo"(foo代表某一变量)

出现这种问题可能是头文件中定义了全局变量foo。

两个文件A.cpp和B.cpp在引入同一变量时,导致编译器会报上述错误。

错误代码:

"Common.h"

#ifndef COMMON_H_  //header guad

#define COMMON_H_

  int foo;  //errormultipule definition of "foo"

#endif


"A.cpp"

#include "Common.h"

  ...do something ...


"B.cpp"

#include "Common.h"

...do something ...

 

 

起因:

  C++支持分别编译,即把头文件和源文件分开。“头文件一般包含类的定义。extern变量的声明和函数的声明。“【1】将类的实现放在源文件中,这样当其他文件需要该类时就只需引入类的头文件即可。

  但是当把一个变量定义在头文件中时就会出现问题,如图1,这样变量foo就在两个文件中被定义了两次,从而导致编译器出现开始的问题。

  

概念:

在提解决办法之前,先给没接触过extern的人讲解下extern的含义:“extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。”【2】

 

extern int foo; // only statement, not definition

 

 

 

意思就是说当你给变量foo之前添加的extern之后,编译器会乖乖地到其他地方找变量foo的定义,此处只是一个声明而已,是为了让编译器知道这个变量存在而不至于报错。(extern的其他作用见条目【2】)

 

解决方案:

  定义一个Common.cpp的文件,里面专门放这些全局变量,同时在Common.h文件中将foo声明为extern int foo,A.cpp和B.cpp分别#include Common.h这样编译器在链接时就可以Common.obj里面找到foo的定义了

 

note: 如果只有extern int foo,同时没有定义foo的内容,那么当A.cpp中用到foo时会提示foo这个对象无法解析;

 

顺便提下在#include时可以根据项目中的路径、项目中的路径以及头文件名来确定头文件保护符,规则为:<PROJECT>_<PATH>_<FILE>_H_

 

参考条目:

【1】.《C++ Primer 中文版》

【2】  http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html

    简要提纲(仅供自己观看,有理解不对的请谅解!)

    1.extern对于变量和函数的作用

    2.extern "C"的作用:以C的方式解析下面的内容,而不是C++,因为C++编译器会将其函数名变换成编译器内部的名称(为了实现重载)

    3.extern char a[]; // 如果定义处以char a[]="abcd"出现,则声明处不能定义成extern char *a,原因是指针和字符串数组的表示方式不同,所以extern处的声明尽量与定义处保持一致

    4.最好不要把全局的声明和定义放在一起,以免出现重定义的情况

    5.static和extern修饰的变量是一对对头,一个想着猥琐发育,一个想着往外送!

    6.const虽然也和static类似,是作用于本编译模块,但是却可以被extern指定。

 

【3】 Google_Cpp_Style_guide_CN

posted on 2017-09-07 17:37  野蛮小卒  阅读(609)  评论(0)    收藏  举报