其他分享
首页 > 其他分享> > c – 为什么要将整个标题内容放在保护令牌中?

c – 为什么要将整个标题内容放在保护令牌中?

作者:互联网

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

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

那么,如果我们可以将声明放在外面,为什么要使用警卫令牌来保护整个标头呢?

我的理由如下:

当两个标题以某种方式相互引用时,您可能经常遇到问题.您通常会收到未声明的符号错误,而您的第一反应是包含必要的标题.但是当你的两个标题碰巧包含在一起时,你就会得到神秘的错误.

啊:

#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未声明,但包含了标题. (这是一个重量级的时刻.)

这是因为标头守卫不会嵌套:

#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

这里没问题.

更新:将标题包含在警卫中(对不起,这是一个错误).

解决方法:

当你只考虑“声明”时,你错过了一半的故事. C也有一个“类定义”的概念,它是第三种新型动物 – 它既是(类的)定义,也是成员函数的声明.

由于类可能不会被定义多次(就像任何定义一样),因此不能包含带有类定义的头文件多次.

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

输入包括警卫.

标签:c-3,include-guards,c,header-files,header
来源: https://codeday.me/bug/20190723/1514323.html