- 仔细区别pointers和references。指针和引用有些相似,他们本身都是对存在于某个地方的对象(不是指class)的指示,但是他们有着本质的区别。指针变量存储所指对象的地址,所指的对象可以是null,只要可以寻址就行。而引用是某个已经存在对象的别名,所以不可以先声明一个引用,经过一段时间(代码)后让它指向某个对象。
- 最好使用C++转型操作符。C++提供了自己的四种转型操作符:
1) static_cast。拥有与C旧式转型相同的意义与限制,但不能移除表达式的常量性,因为有const_cast做这件事。
2) const_cast。只能用于改变表达式的常量性或变异性。
3) dynamic_cast。只能执行安全的向下转型或跨系转型。如果转型失败,会得到一个null指针或抛出异常。
4) reinterpret_cast。这是一个不具有移植性的转型操作符,常见的用法是对函数指针进行转型,但尽量少用。
使用这些新型转型操作符的方式为:xxxx_cast<类型>(表达式)。从上面可以看出,使用新型转型操作符可以更好地表达语义,增加可读性,转型操作也更加安全。即使使用了更安全的新型转型操作符,转型这种操作能不做就不做,《Effective C++》已经提过这一点。
- 绝对不要以多态方式处理数组。假设有一个双层继承体系class D : public B。另有一个接受B类型数组的函数,函数中依次对数组元素进行处理。如果以一个D类型的数组作为实参传进去可以吗?编译是没问题,数组做参数时与指针一样的(实际上数组和指针有很多不同之处,具体可以见《C专家编程》),表示一个地址嘛。但是运行起来的时候就会出问题,因为指针的类型决定了对待指针指向的内存上的数据的方式,比如double型指针会以8字节为单位对待指针指向的数据,而int型的指针是以4字节为单位。那么同样对于D和B往往会出现他们大小不一样,大小一样,对待他们指向的内存的解决方式就不一样,这就会出错,别忘了可能出错的地方就一定会出错。这里传参是没有问题的,但是函数在运行时会以B类型的方式对待传进来的那个数组名,因而带来了危险。那么多态真的不可以用在数组上吗?我认为可以,使用一个指针数组,而不要直接使用一个对象(class的实例)数组就可以了。本条款我想主要是针对对象数组的。
- 非必要不要提供default constructor。default constructor是指不带任何参数的那么constructor。这样做可以增强安全性,某件商品通过标识号唯一标识,那么构造一个没有标识号的商品对象显然就是错误的,所以default constructor就该被禁止,而要提供一个可以初始化商品标识号的constructor。但是没有default constructor有时也会带来不便,声明对象数组时,使用STL容器时(STL容器要求放入其中的对象能够提供default constructor)等等,然而提供default constructor也可能会带来不便,比如可能由于提供了default constructor而在制作一些成员函数时需要检查某些成员变量是否为初始变量或为其他值(假设每个成员变量都会被初始化《Effective C++》中已提及)。但是我觉得把事情做正确总是更重要的,耗费一点编程心力是值得的。对,安全至上。
时间: 2024-10-29 19:10:27