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

2024-03-29

Preface

Google 风格指南列出了前向声明的缺点

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

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

  3. 从命名空间 std:: 前向声明符号会产生未定义的行为。

  4. 确定是否需要前向声明或完整的 #include 可能很困难。用前向声明替换 #include 可以默默地改变代码的含义:

Code:

  // 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. 从标头中向前声明多个符号可能比简单地#includeing 标头更详细。

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

Question

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

由于这是列表中的第一点,因此它似乎也相当重要。


我无法想出一个单一的场景,其中前瞻性声明会当标头更改时跳过必要的重新编译。

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

依赖关系意味着什么hidden?

假设你的文件main.cc needs header.h以便正确构建。

  • If main.cc包括header.h,那么这是一个direct依赖性。

  • If main.cc包括lib.h, 进而lib.h包括header.h,那么这是一个indirect依赖性。

  • If main.cc某种程度上取决于lib.h但如果出现以下情况,则不会生成构建错误lib.h不包括在内,那么我可以称之为hidden依赖性。

我不认为这个词hidden然而,这是一个常见的术语,所以我同意可以对措辞进行细化或扩展。

这是怎么发生的?

I have main.c, lib.h, and types.h.

Here is main.c:

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

Here is lib.h:

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

Here is types.h:

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

Now, main.cc依赖于取决于types.h以便生成正确的代码。然而,main.cc仅直接依赖于lib.h, 它有一个hidden依赖于types.h。如果我在中使用前向声明lib.h,那么这就打破了main.cc。但是main.cc仍然可以编译!

而原因是main.cc休息是因为它不包括types.h, 虽然main.cc取决于声明types.h。前向声明使这成为可能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google 风格指南(前向声明部分) 的相关文章

随机推荐

  • IE 11 平滑滚动不触发中间滚动事件

    如果我们做一个简单的测试用例 例如 document documentElement addEventListener scroll function console log document documentElement scrollT
  • 如何在 VBA for Excel 中引用复选框

    我使用开发人员功能区 gt 插入 gt ActiveX 控件 gt 复选框创建了一个复选框 我想编写一个子代码 当选中该框时 PCAPV10 工作表中的一系列值将复制到 BOM 工作表上的一个范围中 我不确定我是否在代码中正确引用了我的复选
  • OpenGL显示列表大小的限制

    有谁知道将太多 OpenGL 调用放入显示列表中是否会导致其失败 如果是这样 有人估计有多少个电话可以做到这一点吗 和显存有关系吗 我从 JOGL 调用 OpenGL 但我认为这并不重要 根据这个文档页 http www opengl or
  • 将 varchar 值转换为数据类型 int 时转换失败

    我有一个 varchar 1000 列声明为包含所有数字的字段 如下所示 我想执行以下脚本 我需要这个才能工作 Declare PostalCode varchar 1000 0 set PostalCode 7005036 7004168
  • 如何使用ML模型和FastAPI处理多个用户的请求?

    我正在研究通过FastAPI分发人工智能模块的过程 我创建了一个 FastAPI 应用程序 它使用预先学习的机器学习模型来回答问题 在这种情况下 一个用户使用是没有问题的 但是当多个用户同时使用时 响应可能会太慢 那么 当多个用户输入问题时
  • 如何让MySQL像SQLite一样处理字符串,涉及Unicode和排序规则?

    我已经在 SO MySQL 文档和其他地方研究这个问题几个小时了 但仍然找不到令人满意的解决方案 问题是 让 MySQL 像 SQLite 一样处理字符串而不需要任何额外的 智能 转换的最简单方法是什么 例如 以下代码在 SQLite 中完
  • 如何使用 bazel 中的 make 规则链接库构建

    我已经使用构建了一个 lib so在 bazel 中制定规则 https stackoverflow com questions 58035752 building makefile using bazel 如何将此外部 lib so 链接
  • 将“名字姓氏”更改为“姓氏,名字”

    我有一个姓名列表 需要将其从 名字姓氏 转换为 姓氏 名字 Barack Obama Donald J Trump J Edgar Hoover Beyonce Knowles Carter Sting 我用了 G Grothendieck
  • 以编程方式触发 ResponsiveSlides.js

    我在用着响应式幻灯片 js http responsive slides viljamis com 我正在尝试以编程方式更改幻灯片 我已经尝试过两种方法 但都没有成功 调用插件的slideTo来自缩略图上的单击事件的函数 传递它应该转到的幻
  • JavaScript 是否有相当于 VBScript 的 ExecuteGlobal 的功能?

    javascript 中是否有 ExecuteGlobal 的替代方案 Function vbExecuteGlobal parmSCRIPT ExecuteGlobal parmSCRIPT End Function DevGuru 描述
  • 使用 Sumifs() 的更快方法

    我每周有一项任务 需要更新一份报告 目前刚刚超过 50K 行 该报告每周都会增长约 500 行 手动添加新数据后 我运行下面的代码来执行Sumifs 总结数据 数据结构为 A 至 C 列是标准列 数字 字母 数字 D 列包含要求和的数量 整
  • 根据两列删除重复项

    我有这张表 我想要一个 SELECT 来排除标记的行 一般规则是 如果有两行或多行的 controlname AND Brandname AND grouptypes 列相等 然后保留组名不是 Keine Zuordnung 的行 CONT
  • 如何将过滤器应用于具有多个“AND”条件的 DataView

    我有一个DataTable包含一些行 哪个被复制到DataView 现在我的 ID 格式为List
  • 使用 JQuery 从出生日期计算年龄

    我需要使用 JQuery 计算某人从出生日期算起是否已超过 18 岁 var curr new Date curr setFullYear curr getFullYear 18 var dob Date parse this text i
  • DataGridView 复选框列 - 值和功能

    我已在 C 表单中的 DataGridView 中添加了一个复选框列 该功能需要是动态的 您选择一个客户 然后显示他们可以提供服务的所有项目 然后您选择这次希望为其中哪些项目提供服务 不管怎样 代码现在将在 DGV 的开头添加一个复选框 我
  • N 个相同处理器上的任务调度的精确算法?

    我正在寻找精确的算法 可以在 N 个相同的处理器中找到任务调度的最佳解决方案 该算法的时间并不重要 最重要的是一个最佳解决方案 完成最后一个任务时所有处理器的最短时间 理论上描述该算法的方程如下 P Cmax 如果有人有算法 尤其是 Jav
  • Spring Data 返回 List

    我有这个存储库 Repository public interface ProductRepository extends JpaRepository
  • java.lang.NoClassDefFoundError:Lorg/slf4j/Logger

    我正在使用具有 Maven 支持的 Intellij 启动 tomcat 一旦我添加以下 tomcat maven 依赖项
  • 制作 Sequelize 显示表格

    我正在 node js 中创建一个项目 我的页面之一将显示数据库中所有表的列表 我想知道Sequelize是否有 显示表格 之类的功能 Thanks 使用续集showAllSchemas method var sequelize new S
  • Google 风格指南(前向声明部分)

    Preface Google 风格指南列出了前向声明的缺点 前向声明可以隐藏依赖项 允许用户代码在标头更改时跳过必要的重新编译 前向声明可能会因库的后续更改而被破坏 函数和模板的前向声明可以防止标头所有者对其 API 进行其他兼容的更改 例