条款一 仔细区别pointers和references:
(一) 指针与引用的区别:
(1)引用只是对象的一个别名,不是新定义了一个变量,它本身不占内存;指针不同,指针本身占有内存,指针本质上是一个存放变量地址的变量。
(2)reference不能为null,一个引用必须代表某个对象。pointers可以为null。因此,使用引用之前不需测试其有效性,而指针需测试它是否为null。
(3)引用初始化后不能被修改,指针可以被重新赋值。
(4)sizeof(引用):是所指对象的大小;sizeof(指针):则是指针本身的大小。
(5)函数形参时:引用传递和指针传递是不同的。
(二)共同点:都是间接的指向其他对象。
条款二 最好使用C++转型操作符:
(一)C++转型操作符四个:static_cast、const_cast、dynamic_cast和reinterpret_cast。
1.C++转型操作符优点:容易识别;意义严谨。
(二)详细介绍:cast_name<type>(expression)
1.static_cast:
*编译器执行的任何隐式转换都可由static_cast完成。
*用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
~进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
~进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
*把空指针转化为目标类型指针。
2.const_cast:去掉表达式的const性质。
3.dynamic_cast:将基类类型的指针或引用安全地转换为派生类类型的指针或引用。(条件:派生体系中必须有虚函数,即多态)
*在运行时,只有基类指针实际指向派生类对象时,才转换成功。
*使用例如:
if(Derived *derivedPtr=dynamic_cast<Derived*>(basePtr))
{
//基类指针实际指向派生类对象才转换成功,并且derivedPtr将初始化为basePtr所指的Derived对象。
}
else
{
//否则,转换失败,转换结果为0,derivedPtr置为0.
}
*转换后的指针可以调用派生类的非虚函数,而虚函数机制则不能。
4.reinterpret_cast:为操作数的位模式提供较低层次的重新解释,依赖于机器,为了安全使用,必须完全理解所涉及的数据类型,以及编译器实现强制类型转换的细节。常用用途:转化函数指针类型。
条款三 绝对不要以多态方式处理数组:
(一) 多态和指针运算不能混用,数组对象几乎总是会涉及指针的算术运算,所以数组和多态不要混用。
条款四 非必要不要提供default constructor:
(一)不提供default constructor带来的限制:
1.没有很好办法为对象数组中的对象指定constructor自变量。
2.不再适用于许多template-based container classes。
3.Virtual base classes如果缺乏default constructors则比较麻烦,因为virtual base class的构造函数参数必须由欲产生对象的派生层次的最深的class提供。
(二)添加无意义的default constructor也会影响classes的效率。
1.不使用default constructors,你可以预期你产生的对象都会被完全初始化。