如何在main.cpp中使用多个头文件时使用Include-guard
How to Include-guard when using multiple headers on a main.cpp?
我在课程中学习c++,使用Visual Studio 2013,我在main.cpp
上有一个包含守卫的问题。我不能使用class
或#pragma once
(虽然他们工作)由于条件我的教授说。
如果我只使用Coordinates
和Line
,并且我在main.cpp
中使用#include Line.h
(从Line
和Coordinates
中获得代码),这可以正常工作,但是当我添加Rectangle
和Triangle
(都有#include "Line.h"
)时,那么它会抛出"已经定义"的error LNK2005
几次。
缺少什么吗?
这是我的代码:
Coordinates.h
#ifndef Coordinates
#define Coordinates
//Code declaration. Other headers have similar declaration
struct CoordinatesType { double x, y; } coordinates;
void setCoordinates(double x, double y);
CoordinatesType getCoordinates();
#endif
Coordinates.cpp
#include "Coordinates.h"
//Code implementation
Line.h
#ifndef Line
#define Line
#include "Coordinates.h"
//Code declaration
#endif
Line.cpp
#include "Line.h"
#include <math.h>
//Code implementation
Rectangle.h
#ifndef Rectangle
#define Rectangle
#include "Line.h"
//Code declaration
#endif
Rectangle.cpp
#include "Rectangle.h"
//Code implementation
Triangle.h
#ifndef Triangle
#define Triangle
#include "Line.h"
//Code declaration
#endif
main.cpp
#include "Triangle.h"
#include "Rectangle.h"
int main(){
//Do stuff here.
}
如果你需要我添加实现和声明代码,请告诉我,但我觉得它必须与include-guard有关。
编辑:我将在坐标标题中添加代码,以便您可以了解我在做什么,并避免在帖子中消耗大量空间。请记住,我不能使用class Coordinates{}
,因为我的教授限制我不能使用它。
此错误是链接器错误,而不是编译器错误。
标题保护符对链接器不起作用。
您已经成功地防止了在同一翻译单元中对事物的多个声明,但是您没有防止在整个程序中对事物的多个定义。
防止这种情况发生的方法是,嗯,不要那样做。如果你想要包含在多个源文件中,头文件中不应该有任何非内联的、非模板的定义。
在这里,您声明了类型CoordinatesType
,并创建了该类型的对象:
struct CoordinatesType { double x, y; } coordinates;
别那样做!只在源文件中创建CoordinatesType
的实例,而不是在头文件中。否则,每个包含此头文件(直接或间接)的源文件将获得自己的coordinates
对象,并且您的链接器会抱怨名称冲突。
代码应该是:
struct CoordinatesType { double x, y; };
然后,在一个源文件中的coordinates
,您希望在其中使用object&help;或extern
在头文件中的声明。有更好的方法,但我不会在这里一一列举,因为这个话题已经在SO上讨论过了。此外,你的c++书将有一个解释。
但它的长和短是,这与标题保护无关。
正如已经指出的,您的问题与include-guard无关。
你的问题在这一行:
struct CoordinatesType { double x, y; } coordinates;
而结构体
的声明struct CoordinatesType { double x, y; };
可以出现在多个.cpp文件中,只要它是相同的(因为包含了相同的头文件),还可以定义一个变量
CoordinatesType coordinates;
在同一行。因为一个定义只允许一次,你的链接器会报错。
如果你真的需要一个这种类型的全局变量(检查你是否真的需要,因为它可能不是必需的),把你的头改为声明:
struct CoordinatesType { double x, y; };
extern CoordinatesType coordinates;
和使用定义
CoordinatesType coordinates;
只包含一个 cpp-file。
请注意,当只包含Line和Coordinates时不会发生错误,因为您的include-guard工作,并且您只在单个.cpp文件
Coordinates.h没有任何include保护。
当您多次包含它时,它只定义一次坐标,但文件的其余部分被多次包含。
把#endif放到正确的位置。
p。包含保护中使用的标识符应该是永远不会在其他地方偶然使用的标识符。如果有人试图使用名为Line或Triangle的变量,我不会感到惊讶。由于您#define了这些,这将导致非常意想不到的错误。使用类似#define LineHeader_Included__的内容。
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 如何将更多文件夹添加到c++include路径
- 修改生成文件以简化框架 #include 路径
- macOS 致命错误:sys/_types/_int8_t.h:没有此类文件或目录 #include < sys/_types/_int8_t.h>
- /usr/include/c++/7/cstdlib:75:15:致命错误:stdlib.h:没有这样的文件或目录 #i
- 使用 #include 将大量重复代码放入单独的文件中是否可以和/或正常?
- 为什么我不能从同一目录中的另一个文件中 #include 我的类?
- 在目录中查找所有.cpp.h文件(include,src等)的传统方法
- 【MacOSX 10.15.1】使用 odb 生成数据库,致命错误:wchar.h:没有这样的文件或目录 #include < wchar.h>
- 为什么 C++ 编译器在"c:program filesgnu emacsinclude"中查找包含文件?
- pip install uwsgi 失败,出现 /usr/local/include/string/string.h:7:10:致命错误:找不到'sstream'文件?
- 无法将静态二进制文件链接到 #include
- 如果您有Visual Studio 2017 Preview 2更新,您可以为我提供include/iosfwd文件吗?
- LNK1104:无法打开文件"include.obj" - OpenCV
- 编译时得到错误:找不到'QtGui/QAction'文件 #include < QtGui/QAction>
- OSX 10.11.6 Make找不到指定的头文件——include-dir不起作用
- 如何在main.cpp中使用多个头文件时使用Include-guard
- 对于c++中大量的私有类常量声明,任何不从另一个文件#include的理由
- 使用gnu coreutils在C++中查找include-guard类型错误
- 在.cpp(不是.h)中include guard的功能是什么?