为什么《 Google风格指南》不鼓励前瞻性声明? [英] Why does Google Style Guide discourage forward declaration?

查看:141
本文介绍了为什么《 Google风格指南》不鼓励前瞻性声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

并不是说Google样式指南是圣经,但作为一个新手程序员,它似乎是一个很好的参考.

Not to say that the Google Style Guide is the holy bible but as a newbie programmer, it seems like a good reference.

Google样式指南列出了向前声明的以下缺点

The Google Style Guide lists the following disadvantages of forward declaration

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

  1. Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change.

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

A forward declaration may be broken by subsequent changes to the library. Forward declarations of functions and templates can prevent the header owners from making otherwise-compatible changes to their APIs, such as widening a parameter type, adding a template parameter with a default value, or migrating to a new namespace.

从命名空间std ::转发声明符号会产生未定义的行为.

Forward declaring symbols from namespace std:: yields undefined behavior.

很难确定是否需要前向声明或完整的#include.用前向声明替换#include可以静默更改代码的含义:

It can be difficult to determine whether a forward declaration or a full #include is needed. Replacing an #include with a forward declaration can silently change the meaning of 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*)

如果将#include替换为B和D的正向decl,则test()将调用f(void *).

If the #include was replaced with forward decls for B and D, test() would call f(void*).

  1. 从头文件中声明多个符号比仅#include头文件更冗长.

  1. Forward declaring multiple symbols from a header can be more verbose than simply #includeing the header.

构造代码以启用前向声明(例如,使用指针成员而不是对象成员)可以使代码更慢,更复杂.

Structuring code to enable forward declarations (e.g. using pointer members instead of object members) can make the code slower and more complex.

但是,对SO的一些搜索似乎表明,前向声明通常是一个更好的解决方案.

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

因此,鉴于这些看似微不足道的缺点,有人可以解释这种差异吗?

So given these seemingly non-trivial disadvantages, can someone explain this discrepancy?

什么时候可以忽略这些缺点中的某些或全部?

And when is it safe to ignore some or all of these disadvantages?

推荐答案

对SO的某些搜索似乎表明前向声明是 普遍来说是一个更好的解决方案.

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

我不这么认为.您引用的文本是将游击队"前向声明与包括适当的include文件进行比较.对于Google在这里批评的方法,我认为您不会在SO上获得很多支持.糟糕的方法是,不,不要#include包含文件,只为要使用的一些函数和类型编写声明".

I don't think that's what SO says. The text you quote is comparing a "guerilla" forward declaration against including the proper include file. I don't think you'll find a lot of support on SO for the approach Google is criticising here. That bad approach is, "no, don't #include include files, just write declarations for the few functions and types you want to use".

正确的包含文件仍将包含其自己的前向声明,对SO的搜索将表明这是正确的做法,因此我知道您对SO赞成声明的想法.但是Google并不是说图书馆自己的包含文件不应该包含前向声明,而是说您不应该流氓为每个要使用的函数或类型编写自己的前向声明.

The proper include file will still contain forward declarations of its own, and a search on SO will suggest that this is the right thing to do, so I see where you got the idea that SO is in favour of declarations. But Google isn't saying that a library's own include file shouldn't contain forward declarations, it's saying that you shouldn't go rogue and write your own forward declaration for each function or type you want to use.

如果您#include正确的包含文件,并且您的构建链正常工作,那么该依赖项不会被隐藏,并且其余的问题主要都不适用,尽管事实是包含文件包含声明.仍然有一些困难,但这不是Google在这里谈论的问题.

If you #include the right include file, and your build chain works, then the dependency isn't hidden and the rest of the problems mostly don't apply, despite the fact that the include file contains declarations. There are still some difficulties, but that's not what Google is talking about here.

特别是将类型的前向声明与类定义进行比较,(4)给出了一个错误的例子(因为D的前向声明不能表示它是从B派生的,为此您需要使用类定义).还有一种叫做"Pimpl"的技术,确实使小心用于特定目的的前向类型声明.因此,您将再次在SO上看到一些支持,但这与支持每个人通常应该围绕前向声明类而不是#include对其标头进行操作的想法不同.文件.

Looking in particular at forward declarations of types as compared with class definitions for them, (4) gives an example of that going wrong (since a forward declaration of D cannot express that it's derived from B, for that you need the class definition). There's also a technique called "Pimpl" that does make careful use of a forward type declaration for a particular purpose. So again you'll see some support on SO for that, but this isn't the same as supporting the idea that everyone should in general run around forward-declaring classes instead of #includeing their header files.

这篇关于为什么《 Google风格指南》不鼓励前瞻性声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆