c++ - 为什么谷歌风格指南不鼓励前向声明?

标签 c++ forward-declaration google-style-guide

并不是说 Google Style Guide 是圣经,但作为新手程序员,它似乎是一个很好的引用。

Google Style Guide 列出了前向声明的以下缺点

  1. 前向声明可以隐藏依赖项,允许用户代码在 header 更改时跳过必要的重新编译。

  2. 前向声明可能会被库的后续更改破坏。函数和模板的前向声明可以防止 header 所有者对其 API 进行其他兼容的更改,例如扩大参数类型、添加具有默认值的模板参数或迁移到新的命名空间。

    <
  3. 转发声明来自命名空间 std::的符号会产生未定义的行为。

  4. 可能很难确定是否需要前向声明或完整的#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*)

如果 B 和 D 的 #include 被替换为前向声明,test() 将调用 f(void*)。

  1. 从 header 转发声明多个符号可能比简单地#include header 更冗长。

  2. 构建代码以启用前向声明(例如,使用指针成员而不是对象成员)会使代码变得更慢和更复杂。

但是,一些关于 SO 的搜索似乎表明前向声明是普遍更好的解决方案。

鉴于这些看似不重要的缺点,有人可以解释这种差异吗?

什么时候可以安全地忽略部分或全部这些缺点?

最佳答案

some search on SO seemed to suggest that forward declaration is universally a better solution.

我不认为那是 SO 所说的。您引用的文本是将“游击队”前向声明与包含正确的包含文件进行比较。对于谷歌在这里批评的方法,我认为你不会在 SO 上找到很多支持。这种糟糕的方法是,“不,不要 #include 包含文件,只需为您要使用的少数函数和类型编写声明”。

正确的包含文件仍将包含它自己的前向声明,并且对 SO 的搜索将表明这是正确的做法,所以我知道您从哪里得到 SO 支持声明的想法。但是 Google 并不是说​​库自己的包含文件不应该包含前向声明,而是说您不应该无赖地为每个要使用的函数或类型编写自己的前向声明。

如果您 #include 正确的包含文件,并且您的构建链有效,则依赖性不会被隐藏,其余问题大部分不适用,尽管包含文件包含声明。仍然存在一些困难,但这不是 Google 在这里谈论的内容。

特别是将类型的前向声明与它们的类定义进行比较,(4) 给出了一个出错的例子(因为 D 的前向声明不能表示它是从 B,为此你需要类定义)。还有一种称为“Pimpl”的技术确实可以谨慎为特定目的使用前向类型声明。所以你会再次看到对 SO 的一些支持,但这与支持 每个人 通常应该围绕前向声明类而不是 #include< 的想法是不同的正在处理它们的头文件。

关于c++ - 为什么谷歌风格指南不鼓励前向声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36596881/

相关文章:

c++ - 使用循环包含时出现“使用未定义类型”错误

c++ - C++/CLI前向声明

c++ - 尝试在 OpenCv 中使用 sift 匹配两个图像,但匹配太多

c++ - 比较两个map::iterators:为什么需要std::pair的拷贝构造函数?

c++ "Incomplete type not allowed"访问类引用信息时出错(带有前向声明的循环依赖)

c++ - 在不访问其定义的情况下使用头文件中的类?

python - 是否有基于Google风格指南的lint Python工具?

python - Google 风格指南中的可选类型提示

c++ - CLion 灰显包括

c++ - 二进制 gcd 算法 - 不工作