Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用#ifndef时,.h文件被多次添加_C++_C Preprocessor - Fatal编程技术网

C++ 使用#ifndef时,.h文件被多次添加

C++ 使用#ifndef时,.h文件被多次添加,c++,c-preprocessor,C++,C Preprocessor,我尝试使用以下模式 #ifndef TRACER_H #include "Tracer.h" #endif 此is语句添加到代码中的每个文件中,这样tracer.h只添加一次。 但我还是在说多个对象时出错 Tracer.h还包含 #ifndef TRACER_H #define TRACER_H 这里是错误; 我也试过一次布拉格语: 1>Generating Code... 1>Linking... 1>LINK : \\stu05-fsrv.ad.syr.edu\akbh

我尝试使用以下模式

#ifndef TRACER_H
#include "Tracer.h"
#endif
此is语句添加到代码中的每个文件中,这样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 &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVtracer@@@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" (?log@tracer@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@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 &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVtracer@@@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" (?log@tracer@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@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>正在生成代码。。。
1> 链接。。。
1> 链接:\\stu05 fsrv.ad.syr.edu\akbhat$\Visual Studio 2008\Projects\Project3\Debug\Project3.exe未找到或未由最后一个增量链接生成;执行全链接

1> SemiExpression.obj:错误LNK2005:“类std::basic_ostream&__cdecl运算符可能您想了解。它们应该提供您需要的内容。它们是您案例中众所周知的标准模式。

取决于你的编译器,这可能也会很有趣。也许你在这里读到了SO(关于这两个方面还有很多好问题)。

首先,头保护进入文件内部。这使它更容易:

// some_header.h
#ifndef SOME_HEADER_INCLUDED_H
#define SOME_HEADER_INCLUDED_H

// ...

#endif
其次,这些保护仅保护每个翻译单元不受多个包含的影响。如果您有
main.cpp
foo.cpp
,并且每个包含:

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

// ...
每个单元仅包含一次包含防护装置之间的内容,但将定义两次,每个单元一个


当链接时间到来时,您将得到多个定义错误。您需要在一个源文件中定义这些静态变量,并且只在头文件中声明它。

我认为您忘记在include-guard中的
#endif
之后添加
#ifdef
。只需在头文件中使用此模式:

#ifndef HEADERNAME_H
#define HEADERNAME_H

/* code */

#endif
此外,您可能正在头文件中声明对象实例,这些实例最终会在所有源文件中重复并导致链接错误。我需要查看更多代码以了解确切的问题所在,但如果您在头文件中这样说:

Foo myInstance;
您将收到链接器错误,因为符号myInstance引用了多个实例(包含它的每个.cpp文件一个实例),而不是一个。请将上面的一行放在
.cpp
文件中,并将其放在标题中:

extern Foo myInstance;

请向我们展示错误及其发生的周围代码。我创建了Tracer.cpp并在该文件中定义了静态变量log。但是,当我在多个文件中包含Tracer.h时,仍然会出现相同的错误