2016-02-24 44 views
1

我一直在阅读关于标头警卫和他们的用来解决重定义错误,但我不太清楚如何正确实施它。这里是什么,我试图做一个简单的例子:基本的C++重定义错误

fileA.h

#include first_header.h 
#include second_header.h 

// code here 

fileB.h

#include first_header.h 
#include second_header.h 

// code here 

mainfile.cpp

#include fileA.h 
#include fileB.h 

// code here 

现在问题出现在mainfile.cpp中,因为我需要包含fileA.h和fileB.h头文件,但是每个头文件都包含相同的头文件引用,因此给我带来了重定义错误。在这种情况下,我不太确定如何绕过它或正确实施标头警卫。

+6

如果未定义,可以使用#ifndef等预处理程序语句。 –

+1

如果'first_header.h'和'second_header.h'包含警卫,那么应该没有问题。在'mainfile.cpp'中,编译器将打开'fileB.h',然后打开'first_header.h',意识到包含头定义被定义并忽略了文件中的所有内容。 –

+0

请提供[mcve]。你没有显示first_header.h和second_header.h,也没有显示他们有(或没有)他们自己的看守。 –

回答

2

首先,你需要把任何引号或尖括号中的文件名,这样: #include <fileA.h>#include "fileA.h"

从您发布的内容看,您似乎并不了解标头警卫的工作方式。所以这里是破败的。

比方说,我有一个功能,我希望能够从不同的c + +文件调用。你首先需要一个头文件。 (你可以做包括来自内部的包括后卫)。

#ifndef MYHEADER_HPP 
#define MYHEADER_HPP 

#include "first_header.h" 
#include "second_header.h" 

void MyFunction(); 

#endif 

非包括预处理线弥补所谓的“包括警卫,”你应该时刻提防你的头文件。

你然后实现表示函数在.cpp文件,就像这样:如果您使用的是IDE

#include "MyHeader.hpp" 

int main() 
{ 
    MyFunction(); 
} 

#include "MyHeader.hpp" 

void MyFunction() 
{ 
    // Implementation goes here 
} 

现在,您可以使用其他代码此功能编译和链接是为您处理的,但为了以防万一,您可以使用g ++(假设为“main.cpp”文件和“MyFunction.cpp”文件)编译和链接:

g++ main.cpp -c 
g++ MyFunction.cpp -c 
g++ main.o MyFunction.o -o MyExecutable 

我希望这会有所帮助,祝你好运!

+0

谢谢。这是非常丰富的。我对这个还是比较陌生的。 – alduin

+0

@alduin看看这篇关于cplusplus.com的文章,内容非常丰富,并且在开始编程时了解了有关包括守卫的内容:http://www.cplusplus.com/articles/Gw6AC542/](http: www.cplusplus.com/articles/Gw6AC542/)祝您好运! – Dovahkiin

2

逻辑: 检查特定的宏被定义,如果没有定义的宏,定义它与包含头文件的内容。这将防止重复包含标题内容。

像这样:

文件答:

#ifndef fileA_h 
#define fileA_h 

#include first_header.h 
#include second_header.h 

//code here 

#endif 

文件B:

#ifndef fileB_h 
#define fileB_h 

#include first_header.h 
#include second_header.h 

//code here 

#endif 
+0

这有助于进一步理解头卫兵。谢谢。 – alduin

1

大多数编译器(例如Visual Studio)也支持#pragma once它可以用来代替包含表达为“#ifndef”的保护。您会发现在使用MS Visual C++编写的一些遗留代码中。

然而,

#ifndef MYHEADER_HPP 
#define MYHEADER_HPP 

// code here 

#endif 

更便于携带。

+0

这个答案很少有问题。这更像是一条评论。 2. #pragma曾经是一名包括后卫。 3.我可以想到一些不支持#pragma的重要编译器,而编译指示的是,如果不支持它们,它们往往会被默默忽略。确保你的编译器支持它,然后再投入大量的编译指示。 – user4581301

+0

1.你是对的@ user4581301。完全同意。 2.只想提及,“#pragma once”也存在。因为它没有被提及,但是。更多的是告诉OP如果他在其他人的代码中遇到它,意味着它的意思,而不是提议使用它。 3.首先想提到它作为一个评论,但Stackoverflow不允许我写评论,因此我把它放入一个“答案”。 – cwschmidt

+0

更多答案。我建议删除第一段的最后一行,因为这不是传统。只要一些错误和可移植性问题得到解决,“一次”可能就是未来的方式。 – user4581301