条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针所指对象的引用。
l 返回一个局部对象的引用。局部对象在被定义时创建,在离开函数体时被销毁。当函数返回时,程序的控制离开了这个空间,所以函数内部所有的局部对象被自动销毁。因此,如果返回局部对象的引用,那个局部对象其实已经在函数调用者使用它之前被销毁了。
l 返回函数内部用new初始化的指针所指对象的引用。会出现如下问题:
1. 为了避免内存泄漏,就必须确保对每个用new产生的指针调用delete,很容易出现函数中使用了new,返回的是new初始化的指针所指向的对象的引用。这时就必须这样。如下:
const Rational& four = two * two; //得到废弃指针;将它存在一个引用中
delete &four; //得到指针并删除
这样做哪怕只有一个operator*的调用者忘了这条规则,就会造成内存泄漏。
2. 更严重的问题,如operator*的结果只是临时用于中间值,它的存在只是为了计算一个更大的表达式,这时,无法delete。
3. 所以,写一个返回废弃指针的函数无异于坐等内存泄漏的来到。
条款32: 尽可能地推迟变量的定义
好处:
不仅要将变量的定义推迟到必须使用它的时候,还要尽量推迟到可以为它提供一个初始化参数为止。这样做,不仅可以避免对不必要的对象进行构造和析构,还可以避免无意义的对缺省构造函数的调用。而且,在对变量进行初始化的场合下,变量本身的用途会很清晰,所以在这里定义变量有益于表明变量的含义。通过可靠的变量本身来消除对它不必要的注释。所以推迟变量定义可以提高程序的效率,增强程序的条理性,还可以减少对变量含义的注释。