2014-04-24 43 views
0

我想在頭文件中包含C++類的定義和實現。爲頭文件中的類實現防止「已定義」錯誤

我正在創建一個需要C兼容的庫。 .h文件定義了一個C++類,可以通過C++類訪問庫。它也在圖書館內部使用。

由於頭文件被導入到幾個子類,我總是得到「多重定義」錯誤。因爲類定義應該是庫的用戶可導入的,所以我不想將這個實現移到一個單獨的cpp文件中。

你有什麼想法可以解決這個問題嗎?

簡單的例子:

//library: 
typedef struct IFoo{ 
virtual void foo = 0; 
}; 

void library_fun_a(IFoo*); 
void library_fun_b(IFoo*); 

//header file 
#pragma once 
class FooWrapper : public IFoo{ 
    virtual void foo() override; 
}; 
void FooWrapper::foo(){ 
    //some magic here 
} 

[編輯]使用包括警衛,無助於從包括在所有目標文件執行情況,並因此遭遇「多重定義」錯誤鏈接停止編譯。

+0

你錯過在提供[包括警衛(http://en.wikipedia.org/wiki/Include_guard)你的頭文件? –

+2

如果您創建了一個庫,它通常由.h文件組成,並將該實現組成爲包含.o文件的lib *。因此,試圖避免單獨的.c或.cpp文件沒有意義。 – laune

+0

你爲什麼要用這種方式提供實現,而不是用聲明內聯?否則,將實現分離爲額外的編譯單元(如往常一樣)。 –

回答

1

可以輕鬆解決您的倍數確定指標的問題,當你正確內嵌代碼:

class FooWrapper : public IFoo { 
    virtual void foo() override { 
     //some magic here 
    } 
}; 
+0

當然,如果'foo'是非平凡的,你不想用它的定義加載類定義。 (但是,您仍然可以將其內聯,只需提供一個超類定義,然後聲明該內聯。) –

2

您必須使用include guards它們基本上只是宏,它們確定編譯器是否已經包含接口或頭文件中的任何內容。

例如

#ifndef FOO_WRAPPER_H 
#define FOO_WRAPPER_H 

// header contents here ... 

#endif // !FOO_WRAPPER_H 

如果您使用的是微軟的編譯器,你可以在頭文件的頂部使用該指令#pragma once。請注意,這會破壞與其他編譯器的兼容性。

+0

謝謝但這還不夠(我正在使用標頭守護),因爲實現將包含在使用標頭的所有對象文件中 – muffel

+0

@muffel If你有內聯的實現這應該不成問題。 –

+0

將源代碼放在頭文件中會完全破壞頭文件的目的(模板代碼除外)。 –