//---------------------------15/03/29----------------------------

//#9    绝不在构造和析构过程中调头virtual函数

{

/*

1:在构造时调用virtual函数有两个结果

1>如果基类实现了这个函数,就调用基类的函数。

2>基类没有实现这个函数,链接时报错。

原因:

1>基类的构造函数是早于
派生类的构造函数调用的,所以如果virtual函数使用派生类版本的

话,很可能用到未初始化的派生类的成员变量。c++为了不让你走这条危险的路,就会只调用基类的版本

2>根本原因:在调用基类构造函数时,对象类型是base class,所以会调用基类版本。

所以不要在构造函数中调用任何virtual函数。

2:在析构函数中调用vitual函数:

由于派生类的析构函数是先于基类调用的,所以轮到基类的构造函数时,派生类的成员变量依旧呈现

未定义状态。所以c++视它们不存在,在调用基类析构函数时,对象称为一个base class对象。

3:为了在派生类对象创建时,基类中有适当版本的显示信息调用,一个解决办法是由派生类传入一个消息,

再调用non_virtual版本来显示。

*/

}

//#10   令 operator=
返回一个reference to *this

{

/*

关于赋值,c++中可以写成连锁形式:

int x,y,z;

x = y = z = 15;

为了实现这种连锁赋值,赋值操作符必须返回一个reference指向操作符的左侧实参。

*/

class Widget

{

public:

Widget&operator=(const Widget& rhs)

{

...

return *this;

}

};

}

//#11   在operator=中处理自我赋值

{

//看下面的函数

Widget&

Widget::operator=(const Widget& rhs)

{

delete pb;

pb =new Bitmap(*rhs.pb);

return *this;

}

//这样如果是自我赋值,那就先delete了pb,最后pb就指向一个已经删除的对象

//如果让operator=具备异常安全性
往往自动获得自我赋值安全。

Widget& Widget::operator=(const Widget& rhs)

{

Bitmap* pOrig = pb;

pb =new Bitmap(*rhs.pb);

delete pOrig;

return *this;

}

//这么做会有效率问题:如果是自我赋值,那就多做了一次new以及delete;但是考虑到自我赋值的几率

//并不建议在开头加上if判断来判断是否是自己。而且用了if语句,效率会明显下降

//还有种方法是使用swap保证异常安全性

Widget& Widget::operator=(const Widget& rhs)

{

Widget temp(rhs);

swap(temp);

return *this;

}

}

//#12   复制对象时勿忘其每一个成分

{

/*

1:当你自己实现operator=操作时,如果你忘记了一个成员变量的复制,编译器不会警告你

2:当你写自己的operator=或者copy构造函数时应该记得:

1>复制所有的自己的成员变量

2>调用所有base classes内的适当的copying函数。

3:如果发现copy构造函数和copy assignment操作符有相近的代码,消除重复代码的做法是

建立一个init成员函数,供两者调用。(但是考虑到前面的条目,构造函数直接初始化效率会很高,所以

如果相近的代码只是赋值的话,还是多动手的好)

*/

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)

:Customer(rhs), priority(rhs.priority)

{

...

}

PriorityCustomer&

PriorityCustomer::operator=(const PriorityCustomer& rhs)

{

...;

Customer::operator=(rhs);

prioriy = rhs.priority;

return *this;

}

}

effective c++ 笔记 (9-12)的更多相关文章

  1. [Effective JavaScript 笔记] 第12条:理解变量声明提升

    js支持词法作用域,即除了极少的例外,对变量的引用会被绑定到声明变量最近的作用域中. js不支持块级作用域,即变量定义的作用域并不是离其最近的封闭语句或代码块,而是包含它们的函数. 不了解这个会产生一 ...

  2. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  3. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  4. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  5. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  6. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  7. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  8. java effective 读书笔记

    java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...

  9. Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

    原文:[置顶] Android菜鸟的成长笔记(12)——Handler.Loop.MessageQueue 当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要 ...

  10. Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid

    Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid 上一步获取QQ登录网址之后,测试登录之后本该跳转到这个界面 但是报错了: 新建oauth_callback.html & ...

随机推荐

  1. RBAC用户权限管理数据库设计【转载】

    本文转载自:https://www.kancloud.cn/martist/ma_zhao_liu/374123 简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成“用户-角色-权 ...

  2. pong game using ncurses

    bounce2d2.c /* * bounce2d 1.0 * bounce a character (default is 'o') around the screen * defined by s ...

  3. Automation Script For Percona Xtrabackup FULL/Incremental

    This is my first post in 2019, and Im starting with a MySQL solution. In MySQL world, implementing a ...

  4. Zabbix添加Ping外网IP监控

    1.先添加一个HOST,只填写IP即可,如10.1.1.1 2.选择一台客户端,新建item,如下: 3.新建trigger: 注:icmpping[<target>,<packet ...

  5. 检索 COM 类工厂中 CLSID 为 {00021A20-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80080005

    创建Excel对象失败: Excel.Application xApp = new Excel.Application(); 错误提示:{"检索 COM 类工厂中 CLSID 为 {0002 ...

  6. October 10th 2017 Week 41st Tuesday

    If you focus on what you left behind you will never see what lies ahead. 如果你只顾回头看,那么你永远也看不见前方有什么. Ye ...

  7. 51nod 1625 夹克爷发红包

    题目链接戳这里 题意是有一个赋有非负数的矩阵,每次可以将某一行or某一列替换成某个数值,可以替换<=k次,问如何替换能使得矩阵总和最大,输出最大值. 一开始想的是简单的贪心:比如找当前收益最大的 ...

  8. struct与class区别联系(转)

    传送门:struct与class区别联系 注意C中的struct和C++中的struct是不一样的,c中的struct比较原生,仅仅是将一些属性封装起来构成一个整体,没有OO的相关特性.而c++中的s ...

  9. Terminal Service 终端链接

    2008 64位前有这项服务,之后就与远程管理合并了 如果要设置他的连接数可以去 桌面 --> 管理工具 --> 远程桌面服务 最大数设置成1个好了

  10. 使用PhotoShop将视频转为gif格式

    由于文档中不方便上传视频,尤其是一些短视频,将其制作成gif格式更便于浏览,刚好PhotoShop中有这种功能,笔者在这里分享一下. 在PS中打开需要转换格式的视频文件,选择文件选项导出中的导出为We ...