我对头文件的使用有以下疑问.
1 - 在评论后加入警卫
/* Copyright Note and licence information (multiple lines) */
#ifndef FOO_H
#define FOO_H
// Header file contents
#endif
Run Code Online (Sandbox Code Playgroud)
Herb Sutter在他的"C++编码标准"一书中说,像上面这样的代码是有问题的.他说"#ifndef"语句应该出现在头文件的第一行.我觉得这并不令人信服.在头文件中你跟着你们/ gals吗?
2 - 在头文件中使用名称空间
#ifndef FOO_H
#define FOO_H
namespace FooNameSpace{
// Header file contents
}
#endif
Run Code Online (Sandbox Code Playgroud)
上面的代码是否使用了正确的做法?我的意思是,你在头文件中使用命名空间吗?我知道为什么在头文件中导入命名空间是没有意义的,但是如上所述的声明呢?
如果上面的方法是正确的,那么如何对另一个名称空间中的类进行" 转发声明 "呢?是不是
#ifndef FOO_H
#define FOO_H
namespace AnotherNameSpace{
class AnotherFoo; // forward declaration
}
namespace FooNameSpace{
// Use AnotherFoo here
}
#endif
Run Code Online (Sandbox Code Playgroud)
" 前向声明 "是避免" 循环依赖 " 的唯一方法,对吗?
Ada*_*eld 18
包含警卫和评论的顺序纯粹是一种风格问题 - 它不会对编译速度产生任何可衡量的影响.
命名空间绝对应该在头文件中用于声明函数,类,全局变量,等等.你应该有什么不能做的是使用using的语句在头文件-这是不可能UNUSE在包括它的源文件的东西,你不应该强迫包含者在全局范围内添加额外的东西.如果您需要在标题中使用其他名称空间中的内容,请完全限定每个名称.它有时会很痛苦,但它确实是正确的做法.
例子:
// WRONG!
using namespace std;
class MyClass
{
string stringVar;
};
// RIGHT
class MyClass
{
std::string stringVar;
};
Run Code Online (Sandbox Code Playgroud)
至于其他命名空间中的类的前向声明,你已经完全正确了.只记得总是有资格AnotherFoo的AnotherNameSpace::AnotherFoo,当你引用它的水箱内.实际上,前向声明是打破循环依赖的唯一方法.
我听说在包含守卫之前发表评论会导致一些编译器错过优化.如果防护是第一件事,编译器可能会识别成语,甚至不打算打开后续包含的标题.在我自己的代码中,注释通常在include guard之前.我从来没有打扰过测试,看看这是否有任何影响.我可能永远不会(但如果其他人这样做,我会对结果感兴趣).
当然,标题应该包含名称空间 - 否则在名称空间中没有任何用处.但是,正如您所提到的,标题不应该"导入"(因为缺少更好的单词)名称空间到带有' using'指令的编译单元中.
| 归档时间: |
|
| 查看次数: |
17438 次 |
| 最近记录: |