2010-10-26 20 views
0

以下是這種情況: 我有三個文件,Test1.cpp和Test2.cpp。 Test1.cpp可以按原樣編譯爲獨立應用程序。 Test1.cpp還包含一些我想在Test2.cpp中重用的函數。我使用#ifndef #endif塊來有條件地排除Test1.cpp的主函數,以便在編譯Test2.cpp時,Test2.cpp中的主函數將能夠調用Test1.cpp中定義的函數。示例代碼:因爲主要被定義多次關於使用#define有條件地排除主函數的C++預處理器

-------------------------------------------- 
//File: Test1.h 
#include <iostream> 
void do_something(); 
-------------------------------------------- 
//File: Test1.h 
#include "Test1.h" 
void do_something(); 
{ 
    std::cout<<"Done"<<std::endl; 
} 
#ifndef FN_MAIN 
int main() 
{ 
    do_something(); 
    return 0; 
} 
#endif 
-------------------------------------- 
//File: Test2.cpp 
#define FN_MAIN 
#include "Test1.h" 
int main() 
{ 
    do_something(); 
    return 0; 
} 
-------------------------------------- 

調用G ++與Test1.cpp工作正常,並按照我們的期望,但調用G ++與測試2.cpp和Test1.cpp失敗。但是,使用-DFN_MAIN和兩個源文件調用g ++可以解決此問題。有什麼辦法可以解決這個問題嗎?我在想,這個問題來自我對C++預處理器的不完全理解。

注意:我這樣做的動機是減少我正在處理的項目上的代碼大小。實際項目包括獨立版本的Test1.cpp和其他幾個使用Test1.cpp函數的程序。

回答

5

預處理器按順序遍歷每個源文件。在一個.cpp文件中定義的宏不影響另一個.cpp文件中定義的宏。

一個選項是在頭文件中定義FN_MAIN:然後當Test1.cpp包含該頭文件時,宏仍將被定義。但是,我認爲在命令行中定義宏可​​能更清晰。這取決於你的具體用例是什麼。

另一種選擇是將Test1.cppmain()移動到單獨的.cpp文件中,並使用它創建單獨的可執行文件。

+1

在不同的源文件中把主。用'main'以外的所有東西創建'Test1_lib.h'和'Test1_lib.cpp',然後將'main'放入'Test1_main.cpp'中。然後Test2可以使用Test1_lib而不會產生任何衝突。更清潔,並避免宏觀混亂。 – Tim 2010-10-26 00:35:43

2

要解決您的問題這種方式您應該在Test2.cpp中使用#include "Test1.cpp"而不是包含Test1.h,然後只使用Test2.cpp調用g ++。這樣你將編譯一個由Test1.cpp和Test2.cpp所有源組成的編譯單元。

但是 - 這是一個非常糟糕的主意,所以不要這樣做。

你應該做的是將你的工具函數組織成單獨的文件,比如說,最初只是在一個單獨的文件Common.cpp中使用頭文件Common.h來保持事情真的很簡單。然後,將這些文件編譯並鏈接到您要製作的每個可執行文件中。這是做到這一點的正確方式,理解和使用起來要容易得多,並且使用多個源文件不會讓您的應用程序變得更大。

在你的情況,已經動了你的常用方法到發言權Common.cpp/h時,你會那麼做這樣的事情:

g++ Test1.cpp Common.cpp # to build Test1.exe 
g++ Test2.cpp Common.cpp # to build Test2.exe