一、基础议题

条款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. 如何把springboot项目部署到tomcat上

    前言: 开始以为打包springboot项目为war包丢到tomcat上的webapps下面就可以访问controller层的路径了,可是调用接口却报404的错误,而打开8080的主页,不加路径却可以 ...

  2. Ubuntu系统的开机全流程介绍及grub美化

    目录 前言 Ubuntu开机经历的步骤 BIOS Boot Loader Kernel 配置 Grub 的个性化主题 /usr/share/grub/default/grub /etc/default ...

  3. win32 TreeCtrl控件通知消息, LVN_SELCHANGED和LVN_ITEMCHANGED用法

    今天出了个奇怪的问题,当我在主窗口上创建一个用模板对话框的子窗口时, 在子窗口上放的TreeCtrl控件不响应LVN_SELCHANGED消息,也是晕死了, 我以为是消息捕获的问题,我在主窗口上也捕获 ...

  4. Java初步学习——2021.10.12每日总结,第六周周二

    (1)今天做了什么: (2)明天准备做什么? (3)遇到的问题,如何解决? 今天学习了菜鸟教程Java实例,数组 1.数组的排序和元素的查找--sort和binarySearch方法 import j ...

  5. JVM详解(三)——运行时数据区

    一.概述 1.介绍 类比一下:红框就好比内存的运行时数据区,在各自不同的位置放了不同的东西.而厨师就好比执行引擎. 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的 ...

  6. VS2019 及 Visual Assist X 安装配置

    Visual Studio 2019 安装 下载 https://visualstudio.microsoft.com/zh-hans/downloads/ 安装 设置 扩大 Solution Con ...

  7. nsq - 一条消息的生命周期(一)

    经过前面几篇的学习,相信大家对nsq已经有了一个大概的了解,我在写这篇文章的时候也看了很多其他人写的教程,发现大家对于分析系统每个点写的很不错,但是都很少有整体串起来一起走一遍,所以,我打算分成2-3 ...

  8. 【二食堂】Beta - Scrum Meeting 9

    Scrum Meeting 9 例会时间:5.24 20:00~20:20 进度情况 组员 当前进度 今日任务 李健 1. 文本导入.保存部分未完成issue 2. 知识图谱导出的前端issue3. ...

  9. 所驼门王的宝藏(Tarjan)

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  10. Maven还停留在导jar包?快来探索Nexus私服的新世界

    写在前面 Maven,学习框架之前我们都会接触到的一个工具,感觉他的定位,似乎就跟git一样,只是方便我们开发?于是自然而然的,很多小猿对于Maven都只是停留在会用的阶段,利用他来构建,打包,引入j ...