C++ "multiple definition of .. first defined here"

C++ "multiple definition of .. first defined here"

在C++中,有时候需要在不同文件中使用同一个变量。对于这类变量如果处理不当,很容易出现“multiple definition of... first defined here”的错误。

例如,定义了如下3个文件:global.h, a.cpp, b.cpp

//global.h:
#ifndef _GLOBAL_H_
#define _GLOBAL_H_

const int a=1;
int b;

#endif
//a.cpp
#include <iostream>
#include <stdlib.h>
#include "global.h"

using namespace std;

void test1()
{
     cout<<"test1"<<endl;
}
//b.cpp
#include <iostream>
#include <stdlib.h>
#include "global.h"

using namespace std;

void test2()
{
    cout<<"test2"<<endl;
}

void main()
{
  cout<<"hello world"<<endl;
}

执行编译命令:

g++ -o main a.cpp b.cpp

提示错误为:

[chris@zz jojo]g++ -o main a.cpp b.cpp
/tmp/ccc7OcsO.o:(.bss+0x0): multiple definition of `b'
/tmp/ccs7q2VA.o:(.bss+0x0):第一次在此定义

出错原因:a.cpp和b.cpp先分别被编译为.o格式的目标文件,两个目标文件再被链接器链接起来,这当中a.cpp和b.cpp分别进行了一次include,相当于global.h中的代码重复出现了一次。因为a是const类型,所以重新定义也没事;但是b只是普通变量,重复定义显然不行。

显然,一个解决办法是把b定义为const int类型。或者,定义成static int类型也行。

还有一种解决方案,就是把global.h变为global.c文件,a.cpp和b.cpp中不再include它,但是编译的时候把global.c也编译进去,就可以了:

g++ -o main global.c  a.cpp b.cpp

再举一个class相关的例子。比如有Body和Mouth两个类,Body的greet方法会调用Mouth的say方法,而main函数中会调用全局变量body的greet方法。为了只是用一个body和一个mouth对象,可以这么写:

//body.h
#ifndef BODY_H
#define BODY_H

#include <mouth.h>

class Body {
public:
    Body();
    ~Body();
    void greet();
};

extern Body body;

#endif
//body.cpp
#include <body.h>

Body::Body(){}

Body::~Body() {}

void Body::greet()
{
    mouth.say();
}
//mouth.h
#ifndef MOUTH_H
#define MOUTH_H

class Mouth
{
public:
    Mouth();
    ~Mouth();
    void say();
};

extern Mouth mouth;

#endif
//mouth.cpp
#include <mouth.h>
#include <iostream>

using namespace std;

Mouth::Mouth() {}

Mouth::~Mouth() {}

void Mouth::say()
{
    cout << "Have a Nice day!" << endl;
}
//class.cpp
#include <body.h>
#include <mouth.h>

Body body;
Mouth mouth;
//main.cpp
#include <iostream>
#include <body.h>
using namespace std;

int main()
{
    body.greet();
}

上面代码中的include,虽然都是用的尖括号,但因为编译时可以通过指定include路径,不会出问题~
编译命令:

g++ -I ./ mouth.cpp body.cpp class.cpp main.cpp -o main

能够正常运行。

时间: 2024-09-25 13:47:06

C++ "multiple definition of .. first defined here"的相关文章

图片-Vxworks6.8编译bootrom报错multiple definition

问题描述 Vxworks6.8编译bootrom报错multiple definition Vxworks6.8 编译bootrom时报错 板子是MPC8548的板子 之前在别人机子上可以通过编译,考到我机子里就无法编译尝试了重装WindRiver3.2 也无济于事,今天重做了系统后,仍然报相同错误.试过其他人的电脑也报相同错误,但唯独最初给我源码的同事的机子是可以编译通过的 驱动是可以正常编译生产Libhw.a文件的.在生成bootrom的环节报的错. 出现大量的 multiple defin

c语言-关于‘multiple definition of &amp;amp;#39;main&amp;amp;#39;’的一点疑问

问题描述 关于'multiple definition of 'main''的一点疑问 我在Dev-C++里建立了一个项目:Peach: 之后又新建了两个源代码文件: 1.Peach.c #include int main() { int i=0,sum=1; for(i=1;i<=9;i++) { sum=(sum+1)*2; } printf("SUM=%dn",sum); return 0; } 2.Peach_My.c #include int main() { int

MySQL中文参考手册5(安装MySQL上)

mysql|参考|参考手册|中文 MySQL中文参考手册5(安装MySQL上)转载 译者:晏子 [返回][转发] 译者:晏子 (clyan@sohu.com)主页:http://linuxdb.yeah.net4 安装MySQL本章描述怎样获得并安装MySQL:  对于你能从其获得MySQL的站点列表,见4.1 怎样获得MySQL. 要了解支持哪些平台,见4.2 MySQL支持的操作系统. 可获得MySQL的多个版本,以二进制代码和源代码形式分发.为了确定你应该使用的分发的版本和类型,见4.4 

extern作用详解

extern 作用1:声明外部变量 现代编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是 互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部. 例1: 创建一个工程,里面含有A.cpp和B.cpp两个简单的C++源文件: //A.cpp: int iRI; int main() { //..... } //B.cpp int iRI; gcc A.cpp -c gcc B.cpp -c 编译出A.o, B.o都没有问题. 但当gcc A.o B.o -o te

代码从windows下visual studio到andriod平台迁移实现步骤

代码从windows下visual studio到andriod平台迁移实现步骤: 前言 前言也是迁言,从windows的visual studio 2012平台迁移到Android平台上,需用修改挺多的代码和需用注意地方. 我们当然的平台当初就考虑了其他平台跨平台的应用问题,所以一开始在windows下就是用cmake来完成工程的建立的,cMakeLists.txt文件都做了一些处理,但是此时只是更针对或说首先保证windows下的编译和使用. 谨此做个记录. 1. modify cMakeL

div+css非常好的三栏浮动菜单示例

div+css非常好的三栏浮动菜单示例 以下是代码: <html> <head> <title>Free CSS Template 5</title> <style type="text/css" media="screen"><!-- /*  body und schrift deffinitionen */ html { padding:0px; margin:0px; } body { back

提高define性能的php扩展hidef的安装和使用

官网:http://pecl.php.net/package/hidef简介: Allow definition of user defined constants in simple ini files, which are then processed like internal constants, without any of the usual performance penalties. 允许使用简单的ini文件来定义需要的常量,就像使用内部变量一样,而且没有使用Define的性能问

Boost Test学习总结(C++)

1.常用的C++单元测试框架 测试驱动开发(TDD)已经是一种非常流行的开发方式了,在Java和.Net中都提供了非常好的单元测试框架,最近研究C++下面的单元测试,发现其实在C++中还是有很多选择: CPPUnit:著名的XUnit系列产品之一,熟悉JUnit.NUnit的开发人员可以很快上手. CXXTest:需要进行预处理,需要安装Perl或Python. Boost Test:功能强大,提供了自动注册和手动注册两种方式,更重要的是来自千锤百炼的Boost库. Google Test:Go

c++-QT中生成的moc.cpp和静态库函数重定义报错怎么办

问题描述 QT中生成的moc.cpp和静态库函数重定义报错怎么办 QT中生成的moc.cpp和静态库函数重定义报错怎么办.multiple definition这样的 解决方案 换个函数名呗..................... 解决方案二: 把你能够修改的地方修改名字来避免冲突,或者加命名空间来区分