M1:指针与引用的区别
1.指针可以指向空值,但是引用不行,它必须指向某个对象,因此引用必须初始化。
2.引用比指针效率高。
3.指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。
summary:当你知道你必须指向一个对象并且不想改变其指向时,或者在重载操作符并为防止不必要的语义误解时,你不应该使用指针。而在除此之外的其他情况下,则应使用指针。
M2:尽量使用C++风格的类型转换
(static_cast, const_cast, dynamic_cast, 和reinterpret_cast).
const_cast用于类型转换掉表达式的const或volatileness属性
dynamic_cast,它被用于安全地沿着类的继承关系向下进行类型转换。它不能被用于缺乏虚函数的类型上
(参见条款M24),也不能用它来转换掉constness
reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换,转换结果几乎都是执行期定义
(implementation-defined)。因此,使用reinterpret_casts的代码很难移植。转换函数指针的代码是
不可移植的(C++不保证所有的函数指针都被用一样的方法表示),在一些情况下这样的转换会产生不正
确的结果(参见条款M31),所以你应该避免转换函数指针类型,除非你处于着背水一战和尖刀架喉的危
急时刻。
static_cast在功能上基本上与C风格的类型转换一样强大,含义也一样 M3:不要对数组使用多态
语言规范中说通过一个基类指针来删除一个含有派生类对象的数组,结果将是不确定的。多态和指针算法不能混合在一起来用,所以数组与多态也不能用在一起。(array[I]只是一个指针算法的缩写:它所代表的是*(array)。)
无用的缺省构造函数不能确保对象进行了有意义的初始化,成员函数就会因为必须检测成员的有效性而变得复杂, M5:谨慎定义类型转换函数
隐式类型转换运算符只是一个样子奇怪的成员函数:operator 关键字,其后跟一个类型符号。你不用定义函数的返回类型,因为返回类型就是这个函数的名字。
根本问题是当你在不需要使用转换函数时,这些的函数缺却会被调用运行。结果,这些不正确的程序会做出一些令人恼火的事情,而你又很难判断出原因。
克服隐式类型转换运算符的缺点解决方法是用不使用语法关键字的等同的函数来替代转换运算符。例如为了把Rational对象转换为double,用asDouble函数代替operator double函数
通过不声明运算符(operator)的方法,可以克服隐式类型转换运算符的缺点,但是单参数构造函数没有那么简单。
容易的方法是利用一个最新编译器的特性,explicit关键字。
第二就是用 proxy classes
template<class T>
class Array { public: class ArraySize { // 这个类是新的 public: ArraySize(int numElements): theSize(numElements) {} int size() const { return theSize; } private: int theSize; }; Array(int lowBound, int highBound);
Array(ArraySize size); // 注意新的声明
... }; M6:自增(increment)、自减(decrement)操作符前缀形式与后缀形式的区别
UPInt& operator++(); // ++ 前缀 const UPInt operator++(int); // ++ 后缀 UPInt& operator--(); // -- 前缀 const UPInt operator--(int); // -- 后缀 他们返回值类型不同以及后缀操作符应该以前缀操作符为基础来实现 M7:不要重载“&&”,“||”, 或“,” M8:理解各种不同含义的new和delete |
|
来自: My Room 2012 > 《C/C 》