<<More Effective C++>>读书笔记2: 运算符

来源:互联网 发布:java软件开发简历范文 编辑:程序博客网 时间:2024/05/19 02:40

《More Effective C++》+《Effective C++》,两本经典双剑合璧,必然威力无穷。


        Item M5 谨慎定义类型转换函数

1. 两种函数允许编译器进行"自定义类型"转换:单参数构造函数和隐式类型转换运算符。
2. 单参数构造函数是指只用一个参数即可以调用的构造函数。该函数可以是只定义了一个参数,也可以是虽定义了多个参数但第一个参数以后的所有参数都有缺省值。
3. 隐式类型转换运算符是一个成员函数:operator 关键字,其后跟一个类型和符号;不用定义函数的返回类型,因为返回类型就是这个函数的名字。
4. 类型转换函数的根本问题是:当你在不需要使用转换函数时,这些的函数缺却会被调用运行;这些不正确的程序会做出一些意想不到的事情,而你又很难判断出原因。
5. 隐式类型转换符存在会导致错误的发生;解决方法是不使用语法关键字的等同函数来替代转换运算符。
    [使用显式转换函数代替隐式类型转换符]
6. 为了解决隐式类型转换(单参构造函数)而特别引入explicit;构造函数用explicit 声明,如果这样做,编译器会拒绝为了隐式类型转换而调用构造函数。
7. 解决隐式类型转换(单参构造函数)的另外一种方法是:使用Proxy类,Proxy 对象能帮忙更好地控制软件的在某些方面的行为。
8. 让编译器进行隐式类型转换所造成的弊端要大于它所带来的好处,所以除非你确实需要,不要定义类型转换函数。
   
    [这一小节参考总结“自定义类型转换函数”]
   
        Item M6 自增(++)、自减(--)操作符前缀形式与后缀形式的区别
1. 前缀操作符函数与后缀操作符函数的一个区别是后缀操作符函数带参数;它的参数只是用来区分前缀与后缀函数调用。
2. 后缀++函数必须建立一个临时对象以做为它的返回值,这个临时对象必须被构造并在最后被析构。前缀++函数没有这样的临时对象。由此得出一个结论,如果仅为了提高代码效率,应该尽量使用前缀++,少用后缀++,因为它的效率较高。
3. 后缀++和--是根据它们的前缀形式来实现。仅仅需要维护前缀版本,因为后缀形式自动与前缀形式的行为一致。

        Item M7 不要重载“&&”,“||”, 或“,”
1. 布尔表达式短路求值法(short-circuit evaluation),这表示一旦确定了布尔表达式的真假值,即使还有部分表达式没有被测试,布尔表达式也停止运算。
2. 如果重载了&&和||,对&&和||的使用就是函数调用;函数调用法与短路求值法是不同的。首先当函数被调用时,需要运算其所有参数,所以调用函数 operator&& 和 operator||时,两个参数都需要计算,换言之,没有采用短路计算法。第二是C++语言规范没有定义函数参数的计算顺序,所以没有办法知道表达式1 与表达式2 哪一个先计算。完全可能与具有从左参数到右参数计算顺序的短路计算法相反。
3. 逗号操作符用于组成表达式,结果为逗号左右两边的值。
   如果重载逗号表达式,将首先计算逗号左边的表达式,然后计算逗号右边的表达式;整个表达式的结果是逗号右边表达式的值。
4. 操作符重载的目的是使程序更容易阅读,书写和理解,而不是用你的知识去迷惑其他人。如果你没有一个好理由重载操作符,就不要重载。
   [重载“&&”,“||”, 或“,”将会改变它们的本意]

        Item M8 理解各种不同含义的new 和delete
1. 有时你有一些已经被分配但是尚未处理的(raw)内存,你需要在这些内存中构造一个对象。你可以使用一个特殊的operator new ,它被称为placement new。
2. 你想在堆上建立一个对象,应该用new 操作符。它既分配内存又为对象调用构造函数。
    如果你仅仅想分配内存,就应该调用operator new 函数;它不会调用构造函数。
    如果你想定制自己的在堆对象被建立时的内存分配过程,你应该写你自己的operator new 函数,然后使用new 操作符,new 操作符会调用你定制的operator new。
    如果你想在一块已经获得指针的内存里建立一个对象,应该用placement new。
    [这一小节的内容和《Effecitve C++》中有许多重复,我在之前也做过总结。]
    [参考“new的理解”]
    [参考“重载new和delete检测内存泄漏 ”]   
    [参考“定制new和delete”]
   
0 0
原创粉丝点击