• 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
    

    能够正常运行。

  • 相关阅读:
    C# FTP操作
    SWUST OJ(963)
    插入排序(折半插入排序)
    SWUST OJ(962)
    SWUST OJ(961)
    SWUST OJ(960)
    SWUST OJ(957)
    SWUST OJ(956)
    SWUST OJ(955)
    SWUST OJ(954)
  • 原文地址:https://www.cnblogs.com/zjutzz/p/4018816.html
Copyright © 2020-2023  润新知