什么类型的头文件不应该被保护以防止多个包含?

时间:2015-05-09 12:09:43

标签: c++ c multiple-inclusions

我阅读了dcmtk源代码,并在ofstdinc.h中找到了评论:

// this file is not and should not be protected against multiple inclusion

哪种头文件不应该可以防止多次包含?

3 个答案:

答案 0 :(得分:12)

预处理器元编程。也就是说,使用包含的文件作为执行某些任务的编译时函数。该函数的参数是宏。例如,您链接的文件的部分如下所示:

// define INCLUDE_STACK to include "ofstack.h"
#ifdef INCLUDE_STACK
#include "dcmtk/ofstd/ofstack.h"
#endif

因此,如果我想要包含"ofstack.h",我会这样做:

#define INCLUDE_STACK
#include "ofstdinc.h"
#undef INCLUDE_STACK

现在,想象一下,有人想要使用标题的这个特定部分:

// define INCLUDE_STRING to include "ofstring.h"
#ifdef INCLUDE_STRING
#include "dcmtk/ofstd/ofstring.h"
#endif

所以他们会做以下事情:

#define INCLUDE_STRING
#include "ofstdinc.h"
#undef INCLUDE_STRING

如果"ofstdinc.h"包含警卫,则不包括在内。

答案 1 :(得分:12)

一个例子是头文件,它们希望您定义一个宏。考虑使用

标题m.h
M( foo, "foo" )
M( bar, "bar" )
M( baz, "baz" )

这可以在其他一些标题中使用:

#ifndef OTHER_H
#define OTHER_H

namespace other
{
    enum class my_enum
    {
#define M( k, v ) k,
#include "m.h"
#undef M
    };

    void register_my_enum();
}

#endif

和其他一些文件(可能的实现):

#include "other.h"

namespace other
{
    template< typename E >
    void register_enum_string( E e, const char* s ) { ... }

    void register_my_enum()
    {
#define M( k, v ) register_enum_string( k, v );
#include "m.h"
#undef M
    }
}

答案 2 :(得分:0)

您几乎总是希望防止多重包含。你不想这样做的唯一一次是,如果你正在用C宏做一些奇特的东西,你因此想要多次包含以获得你想要的代码生成(没有这个随便的例子)。