什么是软件设计?作者认为“令软件做出你希望它做的事情”的步骤和方法。
条款18 让接口容易被使用,不易被误用一个接口不能假设使用者都为“讲道理的人”,开发一个容易被使用,不容易被误用的程序可以做哪些工作呢?
- 函数代替对象 以一个日期类的构造函数为例,说明接口的重要性
class Date
{
public:
Date(int month,int day,int year);
}
用户实际使用的时候可能会顺序调换,无效参数(21月)。可以使用一个外覆类型(wrapper types)来区分过滤掉用户可能不正确输入。本例而言的具体做法是:
struct Day
{
explicit Day(int d):val(d){}
int val;
}
struct Month
{
explicit Month(int m):val(m){}
int val;
}
struct Year
{
explicit Year(int y):val(y){}
int val;
}
class Date
{
public:
Date(const Year& y, const Month& m, const Day& d){...}
}
将接口改成上面这样,用户按照你的设想输入参数:
Date d(30,3,1995); //error,类型不匹配
Date d(Day(30),Month(3),Year(1995)); //error,类型不匹配,顺序
Date d(Year(1995),Month(3),Day(15)); //ok,类型顺序都匹配
当时仍然无法阻止用户输入Month(15)这种操作,因为日期的取值是固定的,其实现阶段最佳的实现方式是enum class,在作者写这本书时尚未支持。
-
const修饰operator* 等操作符
-
尽可以能和内置类型保持一致
-
令factory模式返回指定类型
回忆之前的例子,为了保证调用者使用智能指针管理内存,将createInvestment
的返回值修改为std::shared_ptr
:
Investment * createInvestment(); //构造接口
void getRidOfInvestment(Investment*); //析构函数
std::shared_ptr createInvestment();
默认情况std::shared_ptr是用delete回收资源的,但是这个例子却使用了一个自定义函数getRidOfInvestment
,std::shared_ptr的第二个参数是一个删除器deleter,传递之:
std::shared_ptr createInvestment()
{
std::shared_ptr retVal(nullptr,getRidOfInvestment);//不太清楚书中为什么坚持要用static_cast,nullptr不是可以隐式转换成任何类型吗?
//可能做一些Investment的一些特化操作
//如果能够在std::shared_ptr之前确定,那更倾向于和构造一起
//而不是指向空在指向对象,效率上可能慢一点
//retVal指向真正的对象,retVal.reset(...)
return retVal;
}
最后作者总结了一下使用智能指针的
优点:
- cross-DLL智能指针总能正确调用资源析构
- 智能指针可以消除潜在的内存泄漏
和缺点:
- 大小可能是原始指针(raw pointer)的两倍
- 需要辅助内存
- 速度稍微慢一些
设计class其实就是设计一个新类型,设计目标是和标准体验一致。设计之前应该考虑:
- 新的type应该如何被创建和销毁
- 对象初始化和赋值有什么差别
- 对象拷贝时行为
- 成员变量合法性是否在构造、赋值和setXXX的函数进行了检查、异常处理
- 新类型的继承图系(inheritance graph)
- 需要什么类型转换?显式还是隐式?见条款15
- 什么样的操作和函数对于对象是合理的
- 编译器默默构造的函数行为是否符合预期?条款6
- type的访问控制如何?
- 什么是新type的为声明接口
- 若为一系列的类应该考虑template
- 你真的需要定义一个新type吗?
暂时不能有更深入的理解,毕竟设计好的class是一个非常系统的工程。等以后再继续看吧,留个坑
条款20 宁以pass-by-reference-to-const代替pass-by-value为什么要这么做?
- 拷贝构造是需要成本的
- 继承关系中派生类失去特性
假设我们定义了一个类A:
class A
{
public:
A() { std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?