https://www.cnblogs.com/zjutzz/p/4018816.html
在C++中,有時(shí)候需要在不同文件中使用同一個(gè)變量。對于這類變量如果處理不當(dāng),很容易出現(xiàn)“multiple definition of... first defined here”的錯(cuò)誤。
例如,定義了如下3個(gè)文件: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; }
執(zhí)行編譯命令:
g++ -o main a.cpp b.cpp
提示錯(cuò)誤為:
[chris@zz jojo]g++ -o main a.cpp b.cpp
/tmp/ccc7OcsO.o:(.bss+0x0): multiple definition of `b'
/tmp/ccs7q2VA.o:(.bss+0x0):第一次在此定義
出錯(cuò)原因:a.cpp和b.cpp先分別被編譯為.o格式的目標(biāo)文件,兩個(gè)目標(biāo)文件再被鏈接器鏈接起來,這當(dāng)中a.cpp和b.cpp分別進(jìn)行了一次include,相當(dāng)于global.h中的代碼重復(fù)出現(xiàn)了一次。因?yàn)閍是const類型,所以重新定義也沒事;但是b只是普通變量,重復(fù)定義顯然不行。
顯然,一個(gè)解決辦法是把b定義為const int類型。或者,定義成static int類型也行。
還有一種解決方案,就是把global.h變?yōu)間lobal.c文件,a.cpp和b.cpp中不再include它,但是編譯的時(shí)候把global.c也編譯進(jìn)去,就可以了:
g++ -o main global.c a.cpp b.cpp
再舉一個(gè)class相關(guān)的例子。比如有Body和Mouth兩個(gè)類,Body的greet方法會(huì)調(diào)用Mouth的say方法,而main函數(shù)中會(huì)調(diào)用全局變量body的greet方法。為了只是用一個(gè)body和一個(gè)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,雖然都是用的尖括號,但因?yàn)榫幾g時(shí)可以通過指定include路徑,不會(huì)出問題~
編譯命令:
g++ -I ./ mouth.cpp body.cpp class.cpp main.cpp -o main
能夠正常運(yùn)行。