gpt4 book ai didi

c++ - Google 风格指南(前向声明部分)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:26 28 4
gpt4 key购买 nike

前言

Google 风格指南包含前向声明的缺点列表

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

问题

我对第一点特别感兴趣,因为我无法想出一个单一的场景,其中前向减速将在 header 更改时跳过必要的重新编译。谁能告诉我这是怎么发生的?或者这是谷歌代码库固有的东西?

因为这是列表中的第一点,所以它似乎也很重要。

最佳答案

I cannot come up with a single scenario, where a forward declaration would skip necessary recompilation when headers change.

我觉得这也有点不清楚,也许可以说得更清楚一些。

隐藏依赖项意味着什么?

假设您的文件 main.cc 需要 header.h 才能正确构建。

  • 如果 main.cc 包含 header.h,那么这是一个直接依赖。

  • 如果main.cc包含lib.h,则lib.h包含header.h,那么这是一个间接依赖。

  • 如果 main.cc 以某种方式依赖于 lib.h 但如果 lib.h 不是,则不会生成构建错误包括在内,那么我可能会称其为隐藏依赖项。

不过,我不认为隐藏这个词是一个常见的术语,所以我同意可以改进或扩展该措辞。

这是怎么发生的?

我有 main.clib.htypes.h

这是main.c:

#include "lib.h"
void test(D* x) { f(x); }

这是lib.h:

#include "types.h"
void f(B*);
void f(void*);

这是types.h:

struct B {};
struct D : B {};

现在,main.cc 依赖于 types.h 以生成正确的代码。但是,main.cc 仅直接依赖于 lib.h,它隐藏依赖于 types.h。如果我在 lib.h 中使用前向声明,那么这会破坏 main.cc。然而 main.cc 仍然可以编译!

main.cc 中断的原因是因为它不包含 types.h,即使 main.cc 依赖于types.h 中的声明。前向声明使这成为可能。

关于c++ - Google 风格指南(前向声明部分),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52376111/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com