C++接口类型怎么定义
本篇内容介绍了"C++接口类型怎么定义"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
I.4 Make interfaces precisely and strongly typed(接口类型应该精准且严格)
Reason(原因)
类型是最简单、最好的文档。经过良好定义的类型可以提高易读性,也可以在编译时被检查。同时,类型明确定义的代码通常也会被优化得更好。
Example, don't(反面示例)
Consider:(考虑以下代码)
void pass(void* data); // weak and under qualified type void* is suspicious
调用者无法确定函数可以接受何种类型和数据是否可能被修改(由于没有用const修饰)。注意所有的指针类型都可以隐式转换为void*,因此调用者很容易(随便)提供一个值。
被调用者必须(通过默契)将数据静态转换为未经验证的类型以便使用它。这样的代码易错且冗长。
只有在传递设计上C++无法描述的数据时才可以使用const void* 。否则考虑使用variant或者指向基础类型的指针作为代替手段。
可选项:模板参数经常可以消除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?
调用者在描述一个矩形这一点是明确的,但却不知道具体描述的是那些方面(四角坐标还是边长)。同时,整形数据可以携带任意形式的信息,单位也存在很多可能,因此我们必须猜测四个整形参数的含义。前两个很有可能是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}); // two corners
draw_rectangle(p, Size{10, 20}); // one corner and a (height, width) pair
显然,我们无法通过静态类型系统捕捉所有错误(例如,认为第一个参数是左上角这个事实就是一种惯例(命名和注释))Example, bad(反面示例)
Consider:(考虑以下代码)
set_settings(true, false, 42); // what do the numbers specify?
参数的类型和值没有说明哪种设定将会被修改,也没有说明值的含义。
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类型(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);
}
这个函数可以如下设计以便接受任何单位的时间间隔。
template
void blink_led(duration
time_to_blink) // good -- accepts any unit {
// assuming that millisecond is the smallest relevant unit
auto milliseconds_to_blink = duration_cast
(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++接口类型怎么定义"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!