gpt4 book ai didi

c++ - 为什么要将整个 header 内容放在保护 token 中?

转载 作者:太空狗 更新时间:2023-10-29 20:00:10 24 4
gpt4 key购买 nike

C 和 C++ 区分声明和定义。

您可以多次声明一个符号,但您只能定义一次。通过了解这一点,我有了一个想法,将声明放在守卫之外,而将定义放在守卫内部:

// declarations

int foo(int x, int y);
int bar(int x, int y);

extern double something;

class X;

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H_

#include "otherheader1.h"
#include "otherheader2.h"

// definitions of structures, classes.

class X
{
// blah blah...
};

#endif

通过这种方式,我可以按照我想要的任何顺序包含我的标题。循环依赖可能不会成为问题。

那么,如果我们可以将声明放在外面,为什么还要用保护标记来保护整个 header 呢?

我的理由如下:

当两个 header 以某种方式相互引用时,您可能经常会遇到问题。您通常会收到未声明的符号错误,您的第一个 react 是包含必要的 header 。但是,当您的两个 header 恰好相互包含时,您会遇到神秘的错误。

嗯:

#ifndef A_H
#define A_H

#include "b.h"

class A {B *b;}

#endif

b.h

#ifndef B_H
#define B_H

#include "a.h"

class B {A *a;}

#endif

当您在 b.cpp 中包含 b.h 时,您会在 a.h 中得到一个错误,即 B 未声明但 header 包含在内。 (这是一个糟糕的时刻。)

这是因为 header guards 不会嵌套:

#ifndef B_H
#define B_H

#ifndef A_H
#define A_H

// B_H already defined no include here.

class A {B *b;}

#endif

class B {A *a;}

#endif

如果你把声明放在守卫之外,你可以防止这种情况:

class B; // in b.h

#ifndef B_H
#define B_H

class A; // in a.h

#ifndef A_H
#define A_H

class B; // again from b.h
// B_H already defined no include here, no redefinition.

class A {B *b;}

#endif

class B {A *a;}

#endif

这里没问题。

更新:将 header 包含到守卫中(抱歉,这是一个错误)。

最佳答案

当您只考虑“声明”时,您就错过了一半的故事。 C++ 也有“类定义”的概念,这是第三种新类型的动物——它既是定义(类的)又是声明(的成员函数)。

由于类可能被定义多次(就像任何定义一样),您不能多次包含带有类定义的头文件。 p>

现在假设您在 foo.hpp 中有一些实用程序类 Foo,并且您有两个独立的模块 a.hppb.hpp 都需要 Foo。您的主程序必须包括 a.hppb.hpp,但现在您试图包括 foo.hpp,因此类Foo 的定义,两次。

输入包括守卫。

关于c++ - 为什么要将整个 header 内容放在保护 token 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8533810/

24 4 0