我已经读过使用时会有一些编译器优化,#pragma once这会导致更快的编译.我认为这是非标准的,因此可能造成跨平台兼容性问题.
这是非Windows平台(gcc)上大多数现代编译器支持的东西吗?
我想避免平台编译问题,但也想避免后备警卫的额外工作:
#pragma once
#ifndef HEADER_H
#define HEADER_H
...
#endif // HEADER_H
Run Code Online (Sandbox Code Playgroud)
我应该担心吗?我是否应该在这方面进一步消耗精力?
我对如何将一个简单类的实现和声明代码分成新的头文件和cpp文件感到困惑.例如,我如何分离下一个类的代码?
class A2DD
{
private:
int gx;
int gy;
public:
A2DD(int x,int y)
{
gx = x;
gy = y;
}
int getSum()
{
return gx + gy;
}
};
Run Code Online (Sandbox Code Playgroud) 告诉编译器只包含一次文件有什么意义?默认情况下它不会有意义吗?是否有任何理由多次包含单个文件?为什么不假设呢?是与特定硬件有关吗?
所以我最近讨论了我的工作,其中我质疑使用双重防守对一名后卫的影响.双防护的意思如下:
头文件"header_a.hpp":
#ifndef __HEADER_A_HPP__
#define __HEADER_A_HPP__
...
...
#endif
Run Code Online (Sandbox Code Playgroud)
将头文件包含在头文件或源文件中的任何位置时:
#ifndef __HEADER_A_HPP__
#include "header_a.hpp"
#endif
Run Code Online (Sandbox Code Playgroud)
现在我明白在头文件中使用guard是为了防止多次包含已经定义的头文件,这是常见的并且有很好的文档记录.如果已经定义了宏,则编译器会将整个头文件视为"空白",并防止双重包含.很简单.
我不明白的问题是使用#ifndef __HEADER_A_HPP__和#endif围绕着#include "header_a.hpp".同事告诉我,这为夹杂物增加了第二层保护,但是如果第一层绝对完成工作(或者它是什么?),我看不出第二层是如何有用的.
我能想到的唯一好处是它可以直接阻止链接器找到文件.这是否意味着改善编译时间(没有提到作为一个好处),或者在这里有什么其他工作我没有看到?
我目前正在开展一个大型项目并且维护所有这些包括警卫让我疯狂!手工编写是令人沮丧的浪费时间.虽然许多编辑可以生成包含警卫,但这并没有多大帮助:
编辑器根据文件名生成保护符号.如果在不同目录中具有相同文件名的标头,则会出现此问题.他们两个都会得到相同的包括后卫.将目录结构包含在保护符号中需要编辑器的一些奇特的方法,因为宏中的斜杠和反斜杠不是最好的.
当我必须重命名文件时,我应该重命名所有包含警戒(在ifndef中,定义和理想的endif的注释).烦人.
预处理器充斥着大量的符号,而不知道它们的含义.
然而,定义包含一次,编译器每次遇到标题包含时仍会打开标题.
包含防护不适合命名空间或模板.实际上他们正在颠覆命名空间!
你的守卫符号有可能不是唯一的.
当程序在单个目录中包含少于1000个标头时,它们可能是可接受的解决方案.但是现在呢?它很古老,与现代编码习惯无关.令我困扰的是,这个问题几乎可以通过#pragma once指令完全解决.为什么不是标准?
在现有代码中,我看到#pragma曾经在#include之后使用过
//Some_Header.h
#include "header1.h"
#include "header2.h"
#pragma once
//implementations
Run Code Online (Sandbox Code Playgroud)
代替
//Some_Header.h
#pragma once
#include "header1.h"
#include "header2.h"
//implementations
Run Code Online (Sandbox Code Playgroud)
我认为它总是需要像第二个例子一样,你的#pragma曾经被定义的位置或者预处理器在文件中的任何地方拾取它是否重要?
编辑
我知道#pragma曾经不是标准的一部分,包括警卫,但这不是我的问题.
我听说您应该更喜欢编写内部包含守卫而不是外部包含守卫。
我在互联网上搜索过,但没有找到答案。
这是 Herb & Andrei 所著的 C++ Coding Standards 一书的片段,其中显示了“外部包含保护”:
避免使用旧书中提倡的过时的外部包含保护:
#ifndef FOO_HJNCLUDED_ //NOT recommended
#include "foo.h"
#define FOO_HJNCLUDED_
#endif
Run Code Online (Sandbox Code Playgroud)
现在,这导致了以下问题:
问:
什么是内部包含保护,什么是外部包含保护?两者之间有什么区别,为什么首选内部包含守卫?
我希望答案也提供了一个例子。
编辑:我最终回答了我自己的问题。