一、基础议题

条款1:仔细区别pointers和references

  1. 指针使用*和->,引用使用“.”
  2. 引用必须指向一个已初始化的对象,不能为null,而指针可以指向某个对象,也可以为null
  3. 指针可以被重新赋值指向另一对象,而引用不可变更指向。

条款2:最好使用C++转型操作符

使用C++的转型操作符可以被很好的辨识,精确指明意图。

  1. static_cast:基本拥有与C旧式转型相同的威力,以及相同限制。几乎什么都可以转,但是不能将struct转int,double转指针,不能移除常量性。
  2. const_cast:用来将某个对象的常量性移除。
  3. dynamic_cast:用来执行继承体系中安全的向下转型或跨系转型。可以将指向基类对象的指针或引用转型为指向派生类的指针或引用。如果转型失败,对于指针返回null,对引用返回异常。
  4. reinterpret_cast:转换结果与编译器息息相关,所以不具备移植性。常用来转换函数指针类型,比如一个函数接受void*的函数指针,你可以把返回值为int类型的函数,转化为void*函数指针放进去调用。

条款3:绝不要以多态方式处理数组

派生类通常比其基类对象有更多的数据成员,两者大小不同,而数组内存的计算是以sizeof(数组中的对象)计算的,所以给基类传递派生类类型的数组,会导致数组大小不一致而出现未知错误。

条款4:非必要不提供default constructor

一个类如果缺乏default constructor将会带来:

  1. 产生数组时,一般而言没有任何方法为数组对象指定constructor自变量。
  2. 将不适用于template-based container classes,对模板来说,被实例化的目标类型必须要有default constructor。

二、操作符

条款5:对定制的“类型转换函数:保持警觉

有两种函数允许编译器进行转换:单参数构造函数(single-argument constructors)和隐式类型转换运算符。单参数构造函数是指只用一个参数即可调用的构造函数。该函数可以是只定义了一个参数,也可以是虽定义了多个参数但第一个参数以后的所有参数都有缺省值。

隐式类型转换运算符只是一个成员函数:operator关键字,其后跟一个类型符号。

1.explicit关键字是为了解决隐式类型转换而特别引入的。构造函数前用explicit声明,防止隐式转换。

2.定义类似功能的函数,而抛弃隐式类型转换,使得类型转换必须显示调用。例如 String类没有定义对Char*的隐式转换,而是用c_str函数来实施这个转换。

条款6:区别increment/decrement操作符的前置和后置形式

前置式和后置式操作符的实现(++)

后置operator++(int) 的叠加是不允许的,如i++++。

原因有两个:

一是与内建类型行为不一致(内建类型支持前置叠加);

二是其效果跟调用一次 operator++(int) 效果一样,这是违反直觉的。另外,后置式操作符使用 operator++(int),参数的唯一目的只是为了区别前置式和后置式而已,当函数被调用时,编译器传递一个0作为int参数的值传递给该函数。

防止后置式叠加的实现:通过返回const对象。

注:处置用户定制类型时,尽可能使用前置式,因为后置式会产生一个临时对象。

条款7:千万不要重载&&,||和,操作符

char *p = NULL;

if(p != 0 && strlen(p) > 10) { }

上面的代码不会报错,虽然 p 是空指针,但 && 符号采用"骤死式"评估方式,如果 pi == 0 的话,不会执行后面的语句。执行顺序从左到右。如果重载了&&这些操作符,会破坏"骤死式"评估方式,事先需要对两个参数都进行评估,并且未明确定义调用动作中的各参数评估顺序。

逗号操作符情况类似,比如f:

for(int i = 0, j = strlen(s) – 1; i < j; ++i, --j)

编译器首先评估逗号左侧,然后评估右侧,最后整个逗号表达式的结果以逗号右侧的值为代表。

不能重载:

.              .*              ::             ?:

new          delete        sizeof      typeid

static_cast  dynamic_cast  const_cast  reinterpret_cast

你能重载:

operator new        operator delete

operator   new[]    operator delete[]

+    -   *   /   %   ^     &   |     ~

!    =   <   >  +=   -=   *=   /=   %=

^=  &=  |=  <<  >>   >>=  <<=  ==   !=

<=  >=  &&  ||  ++   --    ,   ->*  ->

()  []

条款8:了解各种不同意义的new和delete

1. new operator 和operator new区别

string *ps = new string(“hello”);

new operator 第一用来发分配足够内存,放置某类型对象,第二它调用一个constructor为刚才分配的内存中的那个对象设初值。

Void * operator new(size_t size);

Operator new唯一任务是分配内存,可以被重写或重载,改变其行为。取operator new返回的内存并将之转换成一个对象是new operator的事。

2. placement new:特殊版本的operator new,可以在分配好的原始内存上构建对象。

注:如果你打算将对象产生于heap,使用new operator;如果只是分配内存,调用operator new;如果打算在heap object产生时自己决定内存分配方式,请写自己的operator new,并使用new operator;如果在已分配(并拥有指针)的内存中构造对象,使用placement new

3. delete operator 和operator delete

作用和区别于new一一对应,delete operator先析构对象,再释放内存,而operator delete只释放内存。

4. 数组anrray的内存分配方式

内存不再通过operator new分配,而是通过operator new[]分配,然后对数组中每个对象调用constructo。释放内存通过相应的operator delete[]。

More Effective C++笔记(一)(精心整理)的更多相关文章

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

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

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

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

  3. 2019年Unity学习资源指南[精心整理]

    前言 进入一个领域,最直接有效的方法就是,寻找相关综述性文章,首先你需要对你入门的领域有个概括性的了解,这些包括: 1.主流的学习社区与网站. 2.该领域的知名大牛与热心分享的从业者. 3.如何有效的 ...

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

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

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

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

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

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

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

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

  8. java effective 读书笔记

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

  9. CSS精心整理的面试题

    CSS精心整理的面试题 1.设置边框的样式用border-style实现,设置边框的颜色用border-color实现 2.CSS的语法由选择器.属性.值三部分组成 3.设置一个div的最小宽度为50 ...

  10. Git使用方法(精心整理,绝对够用)转载

    Git使用方法(精心整理,绝对够用)   一.git客户端(本地仓库)的一些操作 1.设置账户(需要和github账户设置一致) git config --global user.name xxx g ...

随机推荐

  1. 国庆出游神器:魔幻黑科技换天造物,让vlog秒变科幻大片!

    摘要:国庆旅游景点人太多,拍出来的照片全是人人人.车车车,该怎么办?不妨试试这个黑科技,让你的出游vlog秒变科幻大片. 本文分享自华为云社区<国庆出游神器,魔幻黑科技换天造物,让vlog秒变科 ...

  2. RAC使用auto rolling的方式打补丁

    11.2.0.4 RAC 某系统主库使用auto rolling的方式打补丁在一节点执行1-5,结束后然后在二节点执行1-5,结束后最后再在某个节点执行6. 1.backup GI_HOME& ...

  3. GDP区域分布图的生成与对比(ArcPy实现)

    一.背景 各地区经济协调发展是保证国民经济健康持续稳定增长的关键.GDP是反映各地区经济发展状况的重要指标.科学准确分析各地区GDP空间分布特征,对制定有效措施,指导经济协调发展具有重要参考价值. 二 ...

  4. redis学习笔记-02 list列表类型命令

    一.lpush key value1 value2 value3 value4(命令将一个或多个值插入到列表头部. 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作) lpush k1 ...

  5. 性能利器 Takin 来了!首个生产环境全链路压测平台正式开源

    6 月 25 日,国内知名的系统高可用专家数列科技宣布开源旗下核心产品能力,对外开放生产全链路压测平台产品的源代码,并正式命名为 Takin. 目前中国人寿.顺丰科技.希音.中通快递.中国移动.永辉超 ...

  6. VS Code C/C++开发环境配置

    VS Code C/C++开发环境配置 一.安装 ​ 1.前往官网下载安装即可 https://code.visualstudio.com/ ​ 2.进入VS Code安装如下插件 二.C/C++开发 ...

  7. 利用 pip 安装 Python 程序包到个人用户文件夹下

    利用 --user 参数,即 pip install --user package_name 这样会将Python 程序包安装到 $HOME/.local 路径下,其中包含三个字文件夹:bin,lib ...

  8. 如何再一台电脑上配置多个tomcat同时运行

    1.配置运行tomcat 首先要配置java的jdk环境,这个就不在谢了  不懂去网上查查,这里主要介绍再jdk环境没配置好的情况下 如何配置运行多个tomcat 2.第一个tomcat: 找到&qu ...

  9. 四万字32图,Kafka知识体系保姆级教程宝典

    本文目录: 一.消息队列 Apache Pulsar Pulsar 与 Kafka 对比 二.Kafka基础 三.Kafka架构及组件 四.Kafka集群操作 五.Kafka的JavaAPI操作 六. ...

  10. [技术博客] 通过ItemTouchHelper实现侧滑删除功能

    通过ItemTouchHelper实现侧滑删除功能 一.效果 二.具体实现 demo中演示的这种左滑删除的效果在手机APP中比较常用,安卓也为我们提供了专门的辅助类ItemTouchHelper来帮助 ...