2010-04-18 28 views
0

我試圖使用以下模式。雖然使用#ifndef,.h文件被多次添加

#ifndef TRACER_H 
#include "Tracer.h" 
#endif 

這是聲明被添加到代碼中的每個文件,使tracer.h只添加一次。 仍然我收到一個錯誤說多個對象。

另外Tracer.h包含

#ifndef TRACER_H 
#define TRACER_H 

以下是錯誤; 我試圖編譯一次,以及:

1>Generating Code... 
1>Linking... 
1>LINK : \\stu05-fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Debug\Project3.exe not found or not built by the last incremental link; performing full link 
1>SemiExpression.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class tracer &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@@@Z) already defined in main.obj 
1>SemiExpression.obj : error LNK2005: "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > tracer::log" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@A) already defined in main.obj 
1>Tokenizer.obj : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class tracer &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@@@Z) already defined in main.obj 
1>Tokenizer.obj : error LNK2005: "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > tracer::log" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@A) already defined in main.obj 
1>\\stu05-fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Debug\Project3.exe : fatal error LNK1169: one or more multiply defined symbols found 
1>Build log was saved at "file://\\stu05-fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Project3\Debug\BuildLog.htm" 
+1

請告訴我們該錯誤以及它發生周圍的代碼。 – Thomas 2010-04-18 19:54:37

回答

2

首先,標頭守衛進入文件。這使得它更容易:

// some_header.h 
#ifndef SOME_HEADER_INCLUDED_H 
#define SOME_HEADER_INCLUDED_H 

// ... 

#endif 

其次,這些警衛只保護多個包括每翻譯單元。如果你有main.cppfoo.cpp,每個包含:

#include "some_header.h" 
#include "some_header.h" // again 

// ... 

的內容之間的包括防護裝置將被納入只有一次每單位,但會被定義兩次,一次在每個單元。

當鏈接時間到了,你會得到多重定義的錯誤。您需要在一個源文件中定義那些靜態變量,並且只在頭中聲明它。

+0

它似乎是一個正確的答案讓我檢查 – john 2010-04-18 20:14:00

+0

我創建Tracer.cpp並定義該文件中的靜態變量日誌。但當我inculde Tracer.h在多個文件中,我仍然以相同的錯誤 – john 2010-04-18 20:17:20

+0

感謝它的工作 有兩個靜態對象 – john 2010-04-18 20:18:53

0

也許你想了解include guards。他們應該提供你正在尋找的東西。它們是您的案例衆所周知的標準模式。
根據您的編譯器,#pragma once也可能很有趣。也許你在SO上閱讀pragma vs. guard(關於SO的問題還有很多好的問題)。

0

我想你忘了在#ifdef之後把#endif放在你的包括後衛裏。就在頭文件中使用這種模式:

#ifndef HEADERNAME_H 
#define HEADERNAME_H 

/* code */ 

#endif 

此外,你可能會在頭文件,它最終會被複制在您所有的源文件,並導致鏈接錯誤申報對象實例。我需要看到更多的代碼,看看那裏的確切問題,但如果你說的這個頭文件:

Foo myInstance; 

你會得到鏈接錯誤,因爲符號將myInstance是指多個實例(一個爲每個包含它的.cpp文件)而不是一個。相反,把上面一行在.cpp文件,並把這個在你的頭:

extern Foo myInstance; 
相關問題