2012-08-09 89 views
0

我有一個包含這將在a.h使用和「b.h」,進一步,a.hb.h將包括彼此以訪問在定義了一些類的功能的util.h彼此。頭文件包括環和多個定義

//util.h 

#ifndef _UTIL_H_ 
#define _UTIL_H_ 

#include <iostream> 

void foo() 
{ 
    std::cout << "foo\n"; 
} 

#endif 

//a.h, it has a a.cpp 
#ifndef _A_H_ 
#define _A_H_ 

#include "util.h" 
#include "b.h" 

//some classes' definition 

#endif 

//b.h, it has a b.cpp 
#ifndef _B_H_ 
#define _B_H_ 

#include "util.h" 
#include "a.h" 

//some classes' definition 

#endif 

我的問題是,我得到multiple definition錯誤foo。怎麼樣?

我想這個問題可能是,a.h包括util.hb.h,並且b.h包括util.h再次,所以我得到了多個高清錯誤。但它似乎沒有道理,因爲在util.h我寫了#ifndef/#define警衛。

任何人都可以給我一個幫助,謝謝。

+1

多個定義是一個鏈接時錯誤,不應該與你的頭文件(它有聲明,而不是定義)有關。你是如何編譯的? – 2012-08-09 03:44:50

+0

@GordonBailey,我只是用通常的方式編譯它,比如'g ++ main.cpp a.cpp b.cpp'。 – Alcott 2012-08-09 03:49:51

+1

如果你想把函數體放在頭文件中,它應該是'static void foo(){/ * body * /}'。 – user2k5 2012-08-09 03:56:31

回答

6

你的問題是由定義而不是簡單地聲明fooutils.h

在這個例子中,假設我們有引起:

a.cpp

#include "a.h" 

b.cpp

#include "b.h" 

的main.cpp

#include "a.h" 
#include "b.h" 
#include "utils.h" 


int main(){ 
    foo(); 
    return 0; 
} 

預處理之後,但在編譯之前,你的文件現在這個樣子(這是一種簡化的,但你的想法):

a.cpp

void foo() 
{ 
    std::cout << "foo\n"; 
} 

b.cpp

void foo() 
{ 
    std::cout << "foo\n"; 
} 

的main.cpp

void foo() 
{ 
    std::cout << "foo\n"; 
} 

int main(){ 
    foo(); 
    return 0; 
} 

現在,當您編譯,你有foo 3所定義(他們都是相同的,但是這是不相關)。編譯後,鏈接器無法知道對foo的任何給定調用選擇哪個定義,因此它會生成錯誤。

代替在報頭中定義foo,在utils.cpp中定義它,並且僅在utils.h(例如,

utils。^ h

#ifndef _UTIL_H_ 
#define _UTIL_H_ 

void foo(); 

#endif 

,或者交替,宣佈foostaticinline

utils.h

#ifndef _UTIL_H_ 
#define _UTIL_H_ 

static void foo() 
{ 
    std::cout << "foo\n"; 
} 

/* OR */ 

inline void foo() 
{ 
    std::cout << "foo\n"; 
} 


#endif 

這是你只需要,如果你想你的inline做功能。在這種情況下,編譯器需要使用函數的每個翻譯單元的定義,因爲它本質上變成了編譯時宏。

+0

很好地解釋了:+1 =)只是我會做的一個微妙點...通常情況下,你會在頭文件中聲明該函數,並將其定義在源文件中,但有時您可能需要定義函數一個頭 - 這是當提供速度內聯函數時:'inline void foo(){std :: cout <<「foo \ n」; }'。然而,在這種情況下完全沒有意義的事情! – paddy 2012-08-09 04:07:13

+0

乾杯,我會編輯提及內聯函數! – 2012-08-09 04:08:19

+0

那麼,通過'inline'編譯器會將'foo'視爲'static'? – Alcott 2012-08-10 08:08:36