如何在main.cpp中使用多个头文件时使用Include-guard

How to Include-guard when using multiple headers on a main.cpp?

本文关键字:文件 Include-guard main cpp      更新时间:2023-10-16

我在课程中学习c++,使用Visual Studio 2013,我在main.cpp上有一个包含守卫的问题。我不能使用class#pragma once(虽然他们工作)由于条件我的教授说。

如果我只使用CoordinatesLine,并且我在main.cpp中使用#include Line.h(从LineCoordinates中获得代码),这可以正常工作,但是当我添加RectangleTriangle(都有#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__的内容。

相关文章: