一个简答易错的例子##

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

一年后使用这个接口的时候,写了Date d(15,10,2015)或者Date d(2015,10,15),准确的应该是Date d(10,15,2015),欧,多么低级的错误,花了我一个早上的时间去调试这个bug。

解决的方法###

  • 为参数声明自定义类型
struct Day
{
explicit Day(int d):val(d)
{}
int val;
};
struct Month
{
explicit Month(int d):val(d)
{}
int val;
};
struct Year
{
explicit Year(int d):val(d)
{}
int val;
};
class Date
{
public:
Date(const Month& m,const Day& d,const Year& y);
};
Date d(30, 3, 1995); //wrong
Month m(10);
Day m(15);
Year y(2015);
Date(y, m, d); //wrong
Date(m, d, y); //right

这样子声明类型会很麻烦,但是对“接口被误用”却又神奇的疗效

  • 使用预先定义的类
class Month
{
public:
static Month Jan()
{
return Month(1);
}
...
private:
explicit Month(int m);
...
};

通过函数返回我们需要的月份,保证参数的正确性。

PS:上面使用函数返回,是为了保证使用的月份实例已经初始化

  • 自定义类型与内置类型保持一致

常见的方法有:加上const。再来一个易错的例子

class INT
{
public
INT(int);
INT opeaator=(INT);
INT operator*(INT);
int val;
};
if(a*b = c)
{...}

我们重新定义了系统的int类型,却发现,在a * b = c成功地通过了编译阶段,这个时候要想不进入if下的程序块真的是难上加难,这很明显违背我们的初衷。假如operator*返回的是const,那么就会限制a * b = c的执行。其实,这只是与内置类型的int符合罢了。所以,自定义的type应该尽量内置类型保持一致,除非我们有个好理由(其实一般我们也找不到这种理由)。

  • 保持接口一致化

假如string使用Length,List使用size返回内部的对象个数,你是不是每次使用的时候都要考虑一下要使用Length还是size?假如不想自己的心灵饱受折磨,请保持功能一致的接口使用方法一致。

  • 在客户之前预防客户的错误

假如createInvestment()返回一个Investment类型的指针给客户,谁也无法保证客户使用完了会正确地释放内存。所以较佳的做法是,先发制人,强迫客户使用智能指针,将返回值修改为std::tr1::share_ptr< Investment >createInves()给客户,这基本消除了发生内存泄露的可能性。

假如客户希望通过getRidOfInvestment()来删除指针,但却希望客户自己完成这件事,那又多了一个通往错误的大门。我们可以在返回智能指针前就先指定好删除器,以免客户遗忘。

std::tr1::shared_ptr< Investment> createInvestment()
{
std::tr1::share_ptr< Investment> retVal(static_cast< Invesment*>(0),
getRidOfInvestment);
retVal = ...; //令retVal指向正确的对象
return retVal;
}

上面的例子中,就算用户忘记了释放内存,最后智能智能share_ptr也会根据getRidOfInvestment正确地释放,从而减少了内存泄露的可能性。

实际上,使用了share_ptr的好处不仅仅如此。当使用了dll的时候,假如在一个dll中获得了指针,在另一个dll中依然能通过原来的dll对指针进行删除。从而用户无需在意cross dll problem的问题。

C++设计与声明——让接口容易被正确使用的更多相关文章

  1. Effective C++笔记:设计与声明

    条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. 2,“促进正使用”的办法包括接口的一致性,以及与内置类型的行为兼容. ...

  2. Effective C++笔记04:设计与声明

    条款18:让接口easy被正确使用,不易被误用 1,好的接口非常easy被正确使用,不easy被误用.你应该在你的全部接口中努力达成这些性质. 2,"促进正使用"的办法包含接口的一 ...

  3. EffectiveC++ 第4章 设计与声明

    我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter4 设计与声明 Designs and Declarat ...

  4. 《Effective C++》设计与声明:条款18-条款25

    条款18:让接口容易被正确使用,不容易被误用 注意使用const,explicit,shared_ptr等来限制接口. 必要时可以创建一些新的类型,限制类型操作,束缚对象等. 注意保持接口的一致性,且 ...

  5. Effective C++ —— 设计与声明(四)

    条款18 : 让接口容易被正确使用,不易被误用 欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么样的错误操作.  1. 明智而审慎地导入新类型对预防“接口被误用”有神奇疗 ...

  6. Effective C++笔记(四):设计与声明

    参考:http://www.cnblogs.com/ronny/p/3747186.html 条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接 ...

  7. 《Effective C++》第4章 设计与声明(2)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  8. 《Effective C++》第4章 设计与声明(1)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  9. 【Effective C++】设计与声明

    条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. 2,“促进正使用”的办法包括接口的一致性,以及与内置类型的行为兼容. ...

随机推荐

  1. PHP关于函数的参数问题

    可能是自己以前写程序太规范了,今天发现个PHP函数参数个数的问题,定义的函数有三个参数,但是使用函数的时候竟然传了四个参数,更意外的是程序运行没有错误,甚至没有警告.于是依靠搜索引擎和PHP文档仔细查 ...

  2. Django - Cookie、Session、自定义分页和Django分页器

    2. 今日内容 https://www.cnblogs.com/liwenzhou/p/8343243.html 1. Cookie和Session 1. Cookie 服务端: 1. 生成字符串 2 ...

  3. 史上最全的MonkeyRunner自动化测试从入门到精通(1)

    原文地址https://zhuanlan.zhihu.com/p/26043620 MonkeyRunner使用 #-*- coding:utf-8 –*- from com.android.monk ...

  4. python16_day38【flask】

    一.简介 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预 ...

  5. c/c++值传递和引用传递

    今天看数据结构的时候,因为是c语言版的,刚开始学的时候就对指针搞的焦头烂额,今天,发现参数传递的时候,&符号也莫名其妙,搜了一篇好文,转载下来. 一. 函数参数传递机制的基本理论 函数参数传递 ...

  6. 004-notepad++安装。

    1.下载地址. 官网:https://notepad-plus-plus.org/ 2.安装.

  7. FTRL与Online Optimization

    1. 背景介绍 最优化求解问题可能是我们在工作中遇到的最多的一类问题了:从已有的数据中提炼出最适合的模型参数,从而对未知的数据进行预测.当我们面对高维高数据量的场景时,常见的批量处理的方式已经显得力不 ...

  8. 20155239 2016-2017-2 《Java程序设计》第7周学习总结

    教材学习内容总结 1.了解Lambda语言 "Lambda 表达式"(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的 ...

  9. Putty出现 Network error:Software caused connection abort

    使用centos7.5 用Putty连接使用没多久就会出现 Network error:Software caused connection abort #修改sshd配置文件.修改3项配置即可 vi ...

  10. SQL学习笔记之SQL查询练习题1

    (网络搜集) 0x00 表名和字段 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id ...