【发布时间】:2016-08-04 11:01:41
【问题描述】:
并不是说谷歌风格指南是圣经,但作为一个新手程序员,它似乎是一个很好的参考。
Google 样式指南列出了前向声明的以下缺点
前向声明可以隐藏依赖关系,允许用户代码在标头更改时跳过必要的重新编译。
-
随后对库的更改可能会破坏前向声明。函数和模板的前向声明可以防止标头所有者对其 API 进行其他兼容的更改,例如扩大参数类型、添加具有默认值的模板参数或迁移到新的命名空间。
李> 从命名空间 std:: 转发声明符号会产生未定义的行为。
很难确定是否需要前向声明或完整的#include。用前向声明替换 #include 可以默默地改变代码的含义:
代码:
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)
如果#include 被替换为 B 和 D 的前向 decls,test() 将调用 f(void*)。
从标头前向声明多个符号可能比简单地#includeing 标头更冗长。
构造代码以启用前向声明(例如,使用指针成员而不是对象成员)会使代码变得更慢和更复杂。
但是,对 SO 的一些搜索似乎表明前向声明普遍是更好的解决方案。
那么鉴于这些看似不重要的缺点,有人可以解释这种差异吗?
什么时候可以安全地忽略部分或全部这些缺点?
【问题讨论】:
-
企业风格指南是为最不熟练的企业代码猴子编写的。阅读它们时请记住这一点。第 4 点中给出的示例稍微扩展了这一点。带有
void*类型参数的函数是一个损坏的函数。 -
“但是,对 SO 的一些搜索似乎表明前向声明普遍是更好的解决方案。” [需要引用]
-
谷歌风格指南是为谷歌制作的。除非您是谷歌或类似公司,否则这些规则可能不适用于您。您必须记住,谷歌需要维护大约 1000 万行 C++ 代码,因此“不要使用异常”等一些规则是为了维护,因为重写 1000 万行代码以保证异常安全是不可行的。如果他们要从头开始,他们会做出不同的选择。
-
前向声明会使分层分析(和模块)变得棘手。
-
非 Google 观察者普遍对 AFAIR GSG 持怀疑态度,而不是被认为是“一个很好的参考”。它可能适用于谷歌,正如@nwp 所说,你需要在这种规模的项目中保持一致性......但它不应该被视为一般用户的参考。
标签: c++ forward-declaration google-style-guide