ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Effective C++ T18:让接口容易被正确使用,不易被误用

2021-02-18 22:05:32  阅读:155  来源: 互联网

标签:Effective int 30 C++ Month 接口 Date T18 class


Effective C++学习笔记总链接

改善程序与设计的55个具体做法学习笔记-每日1条


条款18:让接口容易被正确使用,不易被误用

【技巧】

1. 好的接口很容易被正确使用,不容易被误用。你应该在你的所有接口中努力达成这些性质。

2. “促进正确使用”的办法包括接口的一致性,以及与内存类型的行为兼容。

3. “阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任。

4. shared_ptr支持定制型删除器。这可防范DLL问题,可被用来自动解除互斥锁等等。(没读懂。。。下次再细品)


欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么错误

且看下面代码:

class Date
{
public:
	Date(int month, int day, int year);
	...
};

上述代码,客户会犯什么错误呢?

乍一看,这个接口通情达理,但是它的客户很容易犯下至少两个错误。

  • 一、也许会以错误的次序传递参数
Date d(30, 3, 1995); // 应该是 3, 30
  • 二、可能传递一个无效的月份或天数
Date d(2, 30, 1995); // 应该是3, 30

解决办法

导入简单的外覆类型区别天数、月份和年份,然后在Date构造函数中使用这些类型:

class Day // Day class
{
public:
	explicit Day(int d):val(d){}
private:
	int val;
};

class Month // month class
{
public:
	explicit Month(int m):val(m){}
private:
	int val;
};

class Year // year class
{
public:
	explicit Year(int y):val(y){}
private:
	int val;
};

class Date
{
public:
	Date(const Month& m, const Day& d, const Year& y);
	...
}
Date d(30, 3, 1995); // error
Date d(Month(3), Day(30), year(1995)); // ok,类型正确

一旦正确的类型就定位,限制其值有时候是通情达理的。
比较安全的解法是预先定义所有有效的Month

完美解法

class Month
{
public:	
	static Month Jan(){return Month(1);} // 以函数替换对象
	static Month Feb(){return Month(2);} // 表示某个特定月份
	...
	static Month Dec(){return Month(12);}
private:
	explicit Month(int m); // 阻止生成新的月份
	... //这是月份专属数据
};

Date d(Month::Mar(), Day(30), Year(1995));

预防客户错误的另一个办法:const

限制类型内,什么事可以做,什么事不可做,常见的限制是加const

让type容易被正确使用

除非有好理由,否则应该尽量令你的type的行为与内置type一致。(比如和int类型的行为一致)

例如: a, b 为 int,那么a*b赋值并不合法,除非你有好的理由,否则应该让你的type 也有相同的表现。

切记,任何接口如果要求客户必须记得做某些事情,就是有着“不正确使用”的倾向,因为客户可能会忘记做那件事。

Investment* createInvestment();

上述代码至少开启两个客户错误的机会:没有删除指针,或删除同一个指针超过一次。

较佳接口的设计原则是先发制人

std::shared_ptr<Investment> createInvestment();

上式几乎打消了忘记删除底部Investment对象(当它不再被使用时)的可能性

同时shared_ptr可以消除“cross-DLL problem”
这个问题发生在“对象在动态链接程序库(DLL)中被创建,却在另一个DLL内被delete销毁”

定制删除器(抱歉,没读懂。。。以后知识储备够了,再细读)

标签:Effective,int,30,C++,Month,接口,Date,T18,class
来源: https://blog.csdn.net/ZR_YHY/article/details/113843717

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有