《More Effective C++》读书笔记一

来源:互联网 发布:淘宝店铺url 编辑:程序博客网 时间:2024/04/30 09:04

1、关于指针和引用

简单点说就是引用不可能为空,如果你在类成员中定义了引用,则必须在构造函数基/成员初始值设定项列表中初始化

就是这种形式 A():ref(b) 这种形式初始化

引用没法在使用过程中更改指向对象,引用也永远不可能为空,所以你不需要像指针那样用之前都小心翼翼的判定是否为NULL

但同样这样灵活性就下降了

函数参数中,如果要修改某个参数,我个人还是主张完全不用引用而用指针的,QT的设计者就说过,函数参数采用指针的更容易让调用者明白此函数可能会改写某参数的值

得加上&求地址,而引用方式调用却和普通函数一样,想知道函数是否会对参数内容修改得看函数原型才知道

 

2、C++的风格的类型转换

我觉得非常的羞愧,用了这么久C++居然不知道还有C++风格的类型转换,之前只在STL有看到过这种语法,当时的感叹就是C++里居然还有我不知道的关键字,现在才明白是做类型转换用的

平常大家用的都是C风格的转换 int* a = (int*)malloc(10);这种

使用括号,几乎可以在任意类型之间进行转换

而c++定义了4种转换操作符,将原来强大无比的括号转换功能一分为4,更加细化

如果你想把一个double转成int可以这样写:

int i= static_cast<double>(d);

 

而const_cast则是专门用来去除类型的const属性

 

这样就可以将原本的const引用指向的内容修改,我想之所以单独将去除const的类型转换定义为一个操作符,是因为强行去修改一个const类型的数据往往是程序BUG的导火索,单独定义出来方便维护查找

 

dynamic_cast是帮你操作继承体系向下或者横向安全转换的,之所以安全是因为可以知道是否转换成功

 

最后一个是reinterpret_cast,书上说这种转换几乎是不可移植的,我没太明白

反正我用它在做不同类型的指针转换,比如把char*转换为int*

 

四种类型都说完了,如果你要问为什么不直接用C语言的类型转换,既简单又方便

那我知道除非在你肯定还没在混乱的类型转换中吃到足够的苦头,那么等到那时候希望你能想起来C++还提供了更高级更丑陋的转换方式

 

3、不要将多态应用于数组

其实一直以来在建立类数组,就是个很蛋疼的问题,因为你没法简单的让数组中的每个类调用多个参数的构造函数进行初始化(下一节有提到一些撇脚的办法实现)

那就更别说将多态应用与数组了

会产生问题的原因很简单,加入你有个函数需要传入一个类数组,然后你在函数中循环遍历数组进行相关操作,因为我们知道子类可以隐式转换为父类,所以如果传进函数的不是函数声明中的类数组,而是其子类数组,这时候悲剧就发生了

因为程序在遍历数组时,查找下一个元素是从前一个元素的位置,加上一个元素大小,而子类大小都比父类要大,所以当访问第二个元素时就访问的一块无效区域了

 

4、初始化一个类数组,调用多个参数的构造函数技巧

如果有个类CA,这样定义数组

CA ca[10];只能调用默认无参构造函数对10个对象进行初始化,而不能这样

CA ca[10](1);

下面这个方法只能在栈上,就是函数内使用,如果你是想把数组作为类成员什么的是没法办到的

CA ca[] = {CA(1),CA(2),CA(3)....};

当然也可以不声明类数组,而是声明类指针数组,然后初始化时写个for循环一一复制

不过这样会多浪费一些空间

最NB的方法是声明一块内存,将其作为数组内存,然后再调用其构造函数

这里就需要解决几个问题:

1、如果将一块内存用作类数组内存

2、如果手动调用构造函数

第一个问题好解决,调用operator new[]申请内存,然后类型转换为CA*即可,和malloc是一个功能

第二个问题就需要调用placement new了,这个操作符专门用来调用构造函数

使用之前需要引入头文件#include <new>

用法是new (ptr) CA(...);

比普通的new操作符多了一个参数,内存指针ptr

区别就是普通的new自己申请一块内存,然后调用构造函数,而placement new不申请内存,而是在传入的内存块上调用构造函数

所以可以得到下列结论:new 操作符就是由operator new 和 placement new两个操作符组合而成

先申请后构造,这里只是将其拆分开了

最后别忘了需要手动调用析构函数并调用operator delete[]进行内存释放,因为C++编译器不会主动调用非new操作申请的对象的析构

虽然用这个方法来实现再堆上建立类数组太过撇脚

但至少我学会了如何在一块自己分配的内存上调用构造函数

 

原创粉丝点击