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

假如有这样的类:

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

看起来这个接口没错,但是很容易犯下至少两个错误:

Date d(30,3,2019);//错误的次序
Date d(2,30,1995);//应该是3,30,而不是2,30

我们可以通过导入新类型来获得预防比如:

struct Day
{
	int val;
	explicit Day(int d) :val(d) {}
};

struct Month
{
	int val;
	explicit Month(int m) :val(m) {}
};

struct Year
{
	int val;
	explicit Year(int y) :val(y) {}
};

class Date
{
public:
	Date(const Month & m, const Day & d, const Year & y);
	...
};
Date d(30,3,2019);//错误
Date d(Day(30),Month(3),Year(2019));//错误
Date d(Month(3),Day(30),Year(2019));//正确

一旦正确的类型就定位,限制其值有时候是通情达理的。比如一年只有12个月
方法之一是:使用enum,但enum不具备我们希望拥有的类型安全,比如enum可以拿来当作int使用
比较安全的解法是:预先定义所有有效的Months

class Month
{
publicstatic Month Jan(){return Month(1);}
	static Month Feb(){return Month(2);}
	...
private:
	explicit Month(int m);
};
Date d(Month::Mar(), Day(30), Year(2019));

预防错误的另一个方法是:限制类型内什么事可做,什么事不能做。常见的限制是加上const.
任何接口如果要求客户必须记得做某些事情,就是有着“不正确使用”的倾向,比如条款13的工厂函数:

Investment * createInvestment();

可能会导致两个错误:
没有删除指针,或者删除同一个指针超过一次.

条款13表明如何将createInvestment返回值存储于一个智能指针,因而将delete责任推给智能指针。但万一客户忘记了怎么办?
我们可以先发制人,让工厂函数返回一个智能指针:

std::shared_prt<Investment>createInvestment();

假如我们要实现createInvestment并使它返回一个std::shared_prt,但是我们不想使用delete而是使用自己定做的删除器,这样一个接口又可能造成另一个错误,就是使用delete而不是特定的删除器。

针对这个问题,我们也可以先发制人:返回一个绑定删除器的shared_prt.

比如:

std::shared_prt<Investment>p(static_cast<Investment*>(0),getRidOfInvestment);

因此,如果我们要实现createInvestment使它返回一个std::shared_prt并夹带getRidOfInvestment函数作为删除器,代码看起来像这样:

std::shared_prt<Investment>createInvestment()
{
	std::shared_prt<Investment>p(static_cast<Investment*>(0),getRidOfInvestment);
	p = ...;//令p指向正确对象
	return p;
}

如果被p管理的原始指针可以在建立p之前先确定下来,那么我们可以直接将原始指针传给p构造函数会更好。

总结:

1.接口的一致性,以及内置类型的行为兼容可以促进正确使用
2.阻止误用的办法包括建立新类型、限制类型上的操作、束缚对象值,以及消除客户的资源管理责任
3.shared_prt支持定制型删除器。可防范DLL问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值