我是靠谱客的博主 传统苗条,最近开发中收集的这篇文章主要介绍判断void*参数类型_C++核心指南(12) I.4: 使接口精确且强类型I.4: 使接口精确且强类型,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

4242394d84d55810286a36c8d0463980.png

I.4: 使接口精确且强类型

Reason

类型是最简单和最好的文档,其明确的含义提高了可读性,亦可在编译时进行检查。此外,精确类型的代码通常优化得更好。

示例, 不要这样用

Consider:

 void pass(void* data); // 弱类型和未限定的void*是可疑的

调用者不确定什么类型是允许的,由于const没有指定,所以也不确定data是否可变。注意,所有的指针类型都可以被隐藏转换成void*,所以调用者很容易提供这个值(译注:太过随意)。

被调用者必须要static_cast到未确认的类型来使用data(译注:通常不能直接操作void*类型),这是易于出错且啰唆的。

在C++中仅仅使用const void*来传递数据也是难以捉摸的,考虑使用variant或者指针基类的指针。

可先方案: 通常,模板参数可以通过将其转换成T*或T&来消除void*,在泛型代码中T可以通用或概念受限的模板参数。

糟糕的示例

考虑:

 draw_rect(100, 200, 100, 500); // 这些数字指什么? draw_rect(p.x, p.y, 10, 20); // 10和20的单位是什么?

很明显,调用者正在描述一个矩形,但它们关联的部分并不明显,并且int可以携带任意形式的信息,包括许多单位的值,所以我们需要猜测4个int的含义,前面两个很有可能是x和y坐标,但后面两个是什么呢?

虽然注释和参数名字是有帮助的,但是我们可以显示地这样声明:

 void draw_rectangle(Point top_left, Point bottom_right); void draw_rectangle(Point top_left, Size height_width); draw_rectangle(p, Point{10, 20}); // 两个角落(译注:左上,右下) draw_rectangle(p, Size{10, 20}); // 一个角落和一个(height, width)对

显然,我们无法使用静态类型系统来捕获所有的错误(例如,按照惯例(名称和注释)左上角应是第一个参数)。

糟糕的例子

考虑如下:

 set_settings(true, false, 42); //数字指什么?

参数类型及其值没有表达出正在指定的设置或这些值的含义。

(下面)这个设计更加显示、安全且易读:

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

考虑使用枚举(enum)来表示一组布尔值(boolean),这是表示一组布尔值的模式。

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

糟糕的示例

这下面这个示例中,time_to_blink的含义不并能直观地从接口中看出,秒?毫秒?

 void blink_led(int time_to_blink) // 差 -- 单位是有歧义的 { // ... // 使用time_to_blink做一些事 // ... } void use() { blink_led(2); }

好的示例

std::chrono::duration(C++11)有助于显示表达连续时间的单位。

 void blink_led(milliseconds time_to_blink) // 好 -- 单位明确 { // ... // 使用time_to_blink做一些事 // ... } void use() { blink_led(1500ms); }

该函数也可以这样写来接收任意的时间单位:

 template void blink_led(duration time_to_blink) // 好 -- 接收任意单位 { // 假定毫秒是相关的最小单位 auto milliseconds_to_blink = duration_cast(time_to_blink); // ... // 使用milliseconds_to_blink来做事 // ... } void use() { blink_led(2s); blink_led(1500ms); }

强制执行

  • (简单) 报告所有使用void*作为参数或返回值的函数。
  • (简单) 报告不止一个bool类型参数的函数。
  • (很难做到很好) 寻找使用太多基本类型参数的函数

最后

以上就是传统苗条为你收集整理的判断void*参数类型_C++核心指南(12) I.4: 使接口精确且强类型I.4: 使接口精确且强类型的全部内容,希望文章能够帮你解决判断void*参数类型_C++核心指南(12) I.4: 使接口精确且强类型I.4: 使接口精确且强类型所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部