文章出處

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

能夠正常運行。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()