18.接口用于完整的类,使最小。

用户接口类是指程序猿这个类可以访问所获得的接口,典型接口具有在存在唯一功能,好的包装类的数据成员。

这意味着一个完整的接口,包括所有 合理的功能操作。最小指功能和特征尽可能少,不重复。

的函数要少的原因:接口中函数越多。越让其它人难以理解。函数多了会让人混淆。函数多了难以维护,更难维护与升级。长的类定义会导致长的头文件,浪费大量编译时间。

19.分清成员函数。非成员函数和友元函数

成员函数能够是虚函数。即能够实现动态绑定,而非成员函数不行。

关于类一些操作符重载的思考

如 operator+ 进行加法的重载,如果在有理数 Rational 类中有成员函数 +法的操作。则对于一下三个运算:

	result = R1 + R2;
result = R1 + 2;
result = 2 + R1;

先补充一个前提。Rational的构造函数的声明为Rational(int  numerator = 0,int denominator = 1)。则对于第一行的运算。就是为 R1.operator+(R2)。即调用R1中的成员函数,而对于第二行的运算也是正确的,这里将2隐式转换称了Rational类(编译器会对每一个函数的每一个參数运行隐式类型转换)。在没有声明explicit的情况下。即这行编译器是如此解释的 R1.operator+( Rational(2))。而对于第三行的运算是出错的,由于编译器是如此理解这行的操作
2.operator+(R1),在对于整数2找不到相应的operator+函数后。这里并不会隐式将2转换为有理数。编译器又去寻找非成员的全局的operator+( 2,R1)。结果也没有找到,最后搜索失败。

而当将operator+ 作为友元函数时。对于第三行。编译器就如此理解 operator+( 2,R1),2 作为函数的參数,编译器也会尝试隐式转换为有理数类。

可是尽量不要使用友元函数,而使用全局函数,最好可以调用类中的共同拥有接口来实现操作符运算。

由于使用友元函数会带来非常多麻烦。简单点来说,类是为了封装的,友元会减少类的封装性。

20.避免public接口出现数据成员。

简单来说,public中仅仅有函数,对数据成员的读写仅仅通过函数来实现,这样,能够通过设置函数来实现数据成员的 不可读写,仅仅读。仅仅写。可读写。

复杂一点。实现功能分离 functional abstraction ,假设使用函数来实现对数据成员的訪问,当更改对数据成员的设定时。仅仅要在这些函数中进行一些改动,加入一些代码,就能够实现效果,且对用户隐藏这些细节。

21.尽可能使用const。

const除了声明常量外,在类中经常使用于使实參为常量即声明參数为const,以及使函数不改变类内成员的值即声明函数为const,以及让函数的返回值为常量。

让函数的返回值为常量。降低用户出错的几率。

如对operator+的重载,假设返回值不是一个常量。对于这个式子 (a+b) = c,就easy阻止这样的无聊的错误。

声明函数为const,事实上是指函数重载,为const对象调用,而若一个函数仅仅有const的版本号,就会发生将普通对象转换为 const对象,而对于const函数中对const的对象的操作。不能改变const对象中一般数据成员的值 即const函数不能改变对象的成员的值。 可是const函数中对数据成员不进行改变又不是绝对的。假设有指针的数据成员。在函数中不改变指针。但能够去改变指针指向的内容的值, 这种函数也能够通过编译器的检測,但这和我们的为const的定义相违背。还有一种conceptual constness
的观点觉得const成员函数能够改动它所在对象的一些数据。在用户不发觉的情况下,使用keywordmutable。或则能够强制一点。使用const_cast声明一个局部的this指针,然后强制改动这个指针指向的内容的值,这样是能够通过的。

22.尽量传引用,不要传值。

对于传值,函数的形參是通过实參的拷贝来初始化,函数的调用者是函数返回值的拷贝。通过值来传递一个对象,详细含义是由这个对象的类的拷贝构造函数定义的。而这样既浪费空间,又浪费时间。

使用传引用,没有新的对象创建。传递的一直都是引用,则没有构造函数和析构函数的调用。

传引用的还有一个长处是 避免了 分割问题 slicing problem。

当一个派生类的对象被当作基类的对象进行传递时,派生类对象会由 基类的构造函数使用 派生类对象转换得到的基类对象 作为參数 赋值一个新的 完整的基类对象,其派生类中所具有的行为特性会被分割掉。仅仅是一个简单的基类对象。而假设使用了传引用,传给函数中使用的依旧是这个对象本身,而这个对象有多态,有派生类的功能。

对于传引用。

一般都是使用指针来实现的,而对于一些较小的对象,如int。传值事实上会比传引用更加高效。

23.必须返回一个对象时。不要试图返回一个引用。

传引用的一个严重的错误。传递一个并不存在的对象的引用。举例。对于操作符重载中的 operator= , 其返回值为 const T,返回对象的原因:

假设返回为引用,则这个别名的原名是谁,在哪里?实现对于+ ,其返回的对象不是两个參数,而是在函数中新建的对象,而这个对象不能在栈中。由于其在函数结束后就会被释放。而这个别名指向一块已经释放的内存这是不对的。这个对象也不能在堆中,对象不能是动态建立的,由于在调用+后,并没有储存这个别名并释放这个别名所在的内存,这是内存泄漏。所以。不能返回一个引用。所以必须返回一个对象,即使这个对象返回到调用处要 先在函数中进行一次构造和析构,再在调用出进行一次构造,在使用后又要调用一次析构函数,即使花费不低,但仅仅能使用返回对象。

版权声明:本文博主原创文章,博客,未经同意不得转载。

Effective C++ 18-23的更多相关文章

  1. 2016年10月12日 星期三 --出埃及记 Exodus 18:23

    2016年10月12日 星期三 --出埃及记 Exodus 18:23 If you do this and God so commands, you will be able to stand th ...

  2. Effective C++(18) 让接口更容易被正确使用,不易被误用

    问题聚焦:     从这个条款开始,我们把注意力转移到软件设计和声明上来,具体的说就是,C++接口的设计和声明.     所谓软件设计,就是以一般习惯的构想开始,演变成细节的实现,最终开发针对性的特殊 ...

  3. Effective C++ -----条款23:宁以non-member、non-friend替换member函数

    宁可拿non-member non-friend函数替换member函数.这样做可以增加封装性.包裹弹性(packaging flexibility)和机能扩充性.

  4. Effective Java 18 Prefer interfaces to abstract classes

    Feature Interface Abstract class Defining a type that permits multiple implementations Y Y Permitted ...

  5. Rebuild my Ubuntu 分类: ubuntu shell 2014-11-08 18:23 193人阅读 评论(0) 收藏

    全盘格式化,重装了Ubuntu和Windows,记录一下重新配置Ubuntu过程. //build-essential sudo apt-get install build-essential sud ...

  6. effective c++ 条款23 perfer nonmember nonfreind function to member function

    主要的理由还是封装.nonmember nonfreind function 不能访问类private 成员变量. 这个场景是有一个类提供了一些基本功能,比如 class WebBrowser { p ...

  7. 读书笔记 effective c++ Item 23 宁可使用非成员非友元函数函数也不使用成员函数

    1. 非成员非友元好还是成员函数好? 想象一个表示web浏览器的类.这样一个类提供了清除下载缓存,清除URL访问历史,从系统中移除所有cookies等接口: class WebBrowser { pu ...

  8. 18.23 inline函数功能

    GUN的C关键字,在函数定义中函数返回类型前加上关键字inline,可以把函数指定为内联函数.关键字inline必须与函数定义放在一起才能使函数成为内联,仅仅将inline放在函数声明前面不起任何作用 ...

  9. Effective C++ 条款23

    宁non-member.non-friend顶替member性能 本节介绍笔者为什么时间来实现某些功能.择非成员函数而且是非友元函数.这样做总结一句话,就是最大限度的实现类的封装性. 封装意味着不可见 ...

  10. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

随机推荐

  1. [webapi] 如何在查看api时 显示api的说明

    首先在Controller的方法中 写上相关注释,如下图 然后 右击webapi项目点属性.按照下图选择 红色框中内容要保持一致 然后保存. 在项目中找到到这个文件Areas/HelpPage/App ...

  2. UVA11294-Wedding(2-SAT)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=2269">题目链接 题意:有n对夫妻參加一 ...

  3. C++指针和引用简介

    摘要 本文介绍C++指针和概念引用 这是一个指针 指针的类型 指针所指向的类型 指针表达式 指针与函数 什么是引用 指针引用差别 指针和引用的同样点和不同点 **什么是指针** 指针就是一个存放地址的 ...

  4. Flex入门(三)——微架构之Cairngorm

    大家都知道我们在开发后台的时候,都会使用MVC,三层等分层架构,使后台代码达到职责更为分明单一,高内聚低耦合,比如,Dao层仅仅是进行和数据库打交道,负责处理数据:Service(B层)仅仅是进行逻辑 ...

  5. C该结构变化 struct typedef

     这几天看代码,看到若干类型的结构,例如下列结构声明: struct    book{ string name; int price; int num; }; 此种结构定义结构变量的格式例如以下: ...

  6. 小说mvvm

    与多样化和复杂的前,设计模式不再是后端专有名词.从最初的面向对象的,框架制定了到现在为止mvc等一下,今天,它主要是关于Model-View-ViewModel(MVVM). 对于mvc大家可能都会相 ...

  7. C、C++用指针引用的差异

    1:并引述之间的区别在概念的指针 参考是可变的别名.例如 int m; int &n=m; 引用作为一个别名.它在逻辑上不是独立的.它的存在具有依附性.所以引用必须在一開始就被初始化.并且其引 ...

  8. QR代码简单

    QR代码(Quick Response Code, 高速响应码)属于二维矩阵码在一个.由DENSO(日本电装)公司开发,由JIS和ISO将其标准化. QR码分为两种模式:模式1.模式2.当中.模式1相 ...

  9. 前端插件@user

    分享一个 @user 前端插件   开源地址:https://github.com/yuezhongxin/Mention.js 插件效果:类似于微博或 github 中 @user 列表效果. 这是 ...

  10. Android Notification (转)

    上回我们提到在4.0ICS之后,Google为Android平台的Notification这把“倚天剑”注入了更多新鲜的元素,使其更加实用美观.Notification的样式从此变得丰富起来,以适应于 ...