I.4 Make interfaces precisely and strongly typed(接口类型应该精准且严格)

Reason(原因)

Types are the simplest and best documentation, improve legibility due to their well-defined meaning, and are checked at compile time. Also, precisely typed code is often optimized better.

类型是最简单、最好的文档。经过良好定义的类型可以提高易读性,也可以在编译时被检查。同时,类型明确定义的代码通常也会被优化得更好。

Example, don't(反面示例)

Consider:(考虑以下代码)

void pass(void* data);    // weak and under qualified type void* is suspicious

Callers are unsure what types are allowed and if the data may be mutated as const is not specified. Note all pointer types implicitly convert to void*, so it is easy for callers to provide this value.

调用者无法确定函数可以接受何种类型和数据是否可能被修改(由于没有用const修饰)。注意所有的指针类型都可以隐式转换为void*,因此调用者很容易(随便)提供一个值。

The callee must static_cast data to an unverified type to use it. That is error-prone and verbose.

被调用者必须(通过默契)将数据静态转换为未经验证的类型以便使用它。这样的代码易错且冗长。

Only use const void* for passing in data in designs that are indescribable in C++. Consider using a variant or a pointer to base instead.

只有在传递设计上C++无法描述的数据时才可以使用const void* 。否则考虑使用variant或者指向基础类型的指针作为代替手段。

Alternative: Often, a template parameter can eliminate the void* turning it into a T* or T&. For generic code these Ts can be general or concept constrained template parameters.

可选项:模板参数经常可以消除void*而使用T*或者T&。对于一般的代码,这里的T可以是普遍的或者概念约束的模板参数。

译者注:concept是C++20已经决定引入的新概念。

Example, bad(反面示例)

Consider:考虑以下代码:

draw_rect(100, 200, 100, 500); // what do the numbers specify?draw_rect(p.x, p.y, 10, 20); // what units are 10 and 20 in?

It is clear that the caller is describing a rectangle, but it is unclear what parts they relate to. Also, an int can carry arbitrary forms of information, including values of many units, so we must guess about the meaning of the four ints. Most likely, the first two are an x,y coordinate pair, but what are the last two?

调用者在描述一个矩形这一点是明确的,但却不知道具体描述的是那些方面(四角坐标还是边长)。同时,整形数据可以携带任意形式的信息,单位也存在很多可能,因此我们必须猜测四个整形参数的含义。前两个很有可能是x,y坐标对,但是,后两个呢?

Comments and parameter names can help, but we could be explicit:

注释和参数名称可以提供帮助,但是我们可以(通过参数类型)更加清晰地表达:

void draw_rectangle(Point top_left, Point bottom_right);void draw_rectangle(Point top_left, Size height_width);
draw_rectangle(p, Point{10, 20});  // two cornersdraw_rectangle(p, Size{10, 20});   // one corner and a (height, width) pair

Obviously, we cannot catch all errors through the static type system (e.g., the fact that a first argument is supposed to be a top-left point is left to convention (naming and comments)).

显然,我们无法通过静态类型系统捕捉所有错误(例如,认为第一个参数是左上角这个事实就是一种惯例(命名和注释))

Example, bad(反面示例)

Consider:(考虑以下代码)

set_settings(true, false, 42); // what do the numbers specify?

The parameter types and their values do not communicate what settings are being specified or what those values mean.

参数的类型和值没有说明哪种设定将会被修改,也没有说明值的含义。

This design is more explicit, safe and legible:

下面的设计更清晰、安全和可读。

alarm_settings s{};s.enabled = true;s.displayMode = alarm_settings::mode::spinning_light;s.frequency = alarm_settings::every_10_seconds;set_settings(s);

For the case of a set of boolean values consider using a flags enum; a pattern that expresses a set of boolean values.

对于成组使用布尔值的情况,考虑使用枚举类型;下面的模式可以表示一套布尔值。

enable_lamp_options(lamp_option::on | lamp_option::animate_state_transitions);

Example, bad(反面示例)

In the following example, it is not clear from the interface what time_to_blink means: Seconds? Milliseconds?

在下面的例子中,接口没有明确time_to_blink的含义:单位是秒还是毫秒?

void blink_led(int time_to_blink) // bad -- the unit is ambiguous{    // ...    // do something with time_to_blink    // ...}
void use(){    blink_led(2);}

Example, good(范例)()

std::chrono::duration types (C++11) helps making the unit of time duration explicit.

std::chrono::duration类型(C++11)可以让时间间隔的单位更明确。

void blink_led(milliseconds time_to_blink) // good -- the unit is explicit{    // ...    // do something with time_to_blink    // ...}
void use(){    blink_led(1500ms);}

The function can also be written in such a way that it will accept any time duration unit.

这个函数可以如下设计以便接受任何单位的时间间隔。

template<class rep, class period>void blink_led(duration<rep, period> time_to_blink) // good -- accepts any unit{    // assuming that millisecond is the smallest relevant unit    auto milliseconds_to_blink = duration_cast<milliseconds>(time_to_blink);    // ...    // do something with milliseconds_to_blink    // ...}
void use(){    blink_led(2s);    blink_led(1500ms);}

Enforcement(实施建议)

  • (Simple) Report the use of void* as a parameter or return type.

(简单)报告使用void*作为参数或返回值的情况。

  • (Simple) Report the use of more than one bool parameter.

(简单)报告以多个布尔值为参数的情况。

  • (Hard to do well) Look for functions that use too many primitive type arguments.

(很难做好)找到使用太多原始类型参数的函数。

觉得本文有帮助,欢迎点赞并分享给更多的朋友!

更新文章,请关注微信公众号【面向对象思考】

C++核心准则边译边学-I.4 接口类型应该精准且严格相关推荐

  1. C++核心准则边译边学-目标之外

    In.not: Non-aims(目标之外) The rules are not intended to be minimal or orthogonal. In particular, genera ...

  2. C++核心准则边译边学-I.7 说明后置条件

    I.7: State postconditions (说明后置条件) Reason(原因) To detect misunderstandings about the result and possi ...

  3. C++核心准则边译边学-P.12: 酌情使用支持工具

    P.12: Use supporting tools as appropriate(酌情使用支持工具) Reason(原因) There are many things that are done b ...

  4. C++核心准则边译边学-I.6 表达前提条件最好使用Expects()

    I.6: Prefer Expects() for expressing preconditions 表达前提条件最好使用Expects() Reason(原因) To make it clear t ...

  5. C++核心准则边译边学-P.9 不要浪费时间和空间

    P.9: Don't waste time or space(不要浪费时间和空间) Reason(原因) This is C++. 我们在用C++. 译者注:之所以选择C++而不是其他语言,就是希望使 ...

  6. C++核心准则边译边学-I.27 考虑使用指向实现的指针技术获得稳定的ABI

    I.27: For stable library ABI, consider the Pimpl idiom(考虑使用指向实现的指针技术获得稳定的ABI) Reason(原因) Because pri ...

  7. C++核心准则边译边学-I.8 表示后置条件最好使用Ensures()

    I.8: Prefer Ensures() for expressing postconditions(表示后置条件最好使用Ensures()) Reason(原因) To make it clear ...

  8. modbus软件开发实战指南_C++核心准则?GSL:指南支持库

    GSL: Guidelines support library GSL:指南支持库 The GSL is a small library of facilities designed to suppo ...

  9. php 语法 条件变量,C ++核心准则:注意条件变量的陷阱

    今天,我写了一篇关于条件变量的恐怖文章.您应该意识到条件变量的这一问题.C ++核心准则CP 42仅声明:"不要无条件等待". 等待!条件变量支持一个非常简单的概念.一个线程准备一 ...

  10. 开源压缩算法brotli_Google的Brotli压缩算法,C ++核心准则以及更多新闻

    开源压缩算法brotli 在本周的开源新闻综述中,我们将介绍Google的Brotli压缩算法,适用于GitHub的Classroom,C ++ Core Guidelines等! 2015年9月20 ...

最新文章

  1. 连续发表三篇核酸研究数据库文章
  2. python如何安装torch_PyTorch安装与基本使用详解
  3. 分享到facebook链接原格式_神马?!你还不知道Facebook广告怎么操作?
  4. C++基础1 数据类型 常量
  5. cgo的效率 golang_golang CGO FAQ TIPS : cgo 从 C 传递 slice 到 go
  6. iis服务器文件上传大小限制,windows服务器中iis限制文件大小方法
  7. for循环性能优化的几种思路
  8. java动态规划求最大子段和_动态规划-最大子段和
  9. 计算机学科导论-2013级教学材料
  10. Mybatis| Bug合集
  11. gis 六边形网格_六边形网格快速定位
  12. 厦大C语言上机1378
  13. 哀悼日,不发布文章(技术类)!为逝者哀悼!
  14. Sony 入股 Epic,新世代游戏巨头分道扬镳的开始
  15. fmri优缺点_题集|03 EEG、fMRI、PET等的优缺点;经典条件作用的形成及其规律;中介变量和调节变量及其区别;动机与行为效率的关系...
  16. 通过WHQL认证的产品可以在微软官网查询了
  17. 稳定kvm服务器vps,kvm的服务器vps
  18. 国外Cuil搜索引擎 江湖称之为“Google杀手”!
  19. 2018.11.15 《黄金时代》王小波
  20. 计算机数据表示和运算

热门文章

  1. SAP PS 创建预留+采购申请
  2. 如何成为一家顶级域名注册商及如何提供域名注册
  3. Win10下蓝牙音箱无法调节音量的解决方案
  4. java fmail发送邮件_【已实测通过】JavaMail常用的几种邮件发送方式
  5. 网络适配器图标不见了,WLAN以太网都不见了
  6. Java将毫秒(时间戳)转时分秒格式或者年月日
  7. html设计带图形的边框,css怎么设置图片的边框?
  8. 笃情开源:我和 Apache DolphinScheduler 社区的故事
  9. css横排文字光影效果_css实现发光文字,以及一点点js特效
  10. 仿射变换(Affine Transformation)原理及应用(1)