《More effective C++》总结(待补充)
1.指针和引用的使用
禁止使用指向空值的引用,同时使用引用必须初始化,这样,后续使用就不需要像指针一样测试合法性(是否为空等等)。
引用指向第一次初始化的对象,以后不再改变!
重载操作符的时候用引用。
总之 , 多使用引用(如果可以),因为他方便且安全。
2.使用C++风格的类型转
A static_cast 并不是像const_cast去掉const那样去掉变量的static属性,
1)进行显示的基本类型的转换
例如在使用:
int x = 0; double y = 2.33; x= y; // 隐式转换
这样的代码的时候,编译器一般会报warning 告诉你精度变低了 ,使用static_cast 可以告诉编译器:我知道这个损失。warning 就去除了
2)把任意类型的数据转换为void指针
3)把void指针转换为其他类型
用这个方法可以找回:之前储存在void指针中的数据
double a = 1.999; void * vptr = & a; double * dptr = static_cast<double*>(vptr); cout<<*dptr<<endl;//输出1.999
4)将基类的指针转换为派生类指针
PS:从下想上转安全,从上向下不一定安全
int main() { //基类指针转为派生类指针,且该基类指针指向基类对象。 ANIMAL * ani1 = new ANIMAL ; DOG * dog1 = static_cast<DOG*>(ani1); //dog1->OutPuttype();//错误,在ANIMAL类型指针不能调用方法OutPutType();在运行时出现错误。 //基类指针转为派生类指针,且该基类指针指向派生类对象 ANIMAL * ani3 = new DOG; DOG* dog3 = static_cast<DOG*>(ani3); dog3->OutPutname(); //正确 //子类指针转为派生类指针 DOG *dog2= new DOG; ANIMAL *ani2 = static_cast<DOG*>(dog2); ani2->OutPutname(); //正确,结果输出为大黄
return 0; }
这样可以调用派生类的新方法。
但是由于static_cast不进行“安不安全”的检查 , 不如dynamic_cast好
B const_cast : 用于去掉变量的const属性.
const int constant = 21; const int* const_p = &constant; int* modifier = const_cast<int*>(const_p); *modifier = 7;
//o
尽量不更改const,因为结果取决于编译器(未定义行为)
C dynamic_cast 对象指向一个基类(或参考)cast一个指向派生类,dynamic_cast将基于一个基类指针确实是一个指针指向继承类做相应的处理,
即会作一定的推断。
对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
对引用进行dynamic_cast。失败抛出一个异常。成功返回正常cast后的对象引用。
1 #include <stdio.h> 2 3 //动物类 4 class Animal { 5 public: 6 Animal(); 7 ~Animal(); 8 9 virtual void speak() { 10 printf("动物在叫!"); 11 } 12 13 private: 14 15 }; 16 17 Animal::Animal() { 18 } 19 20 Animal::~Animal() { 21 } 22 23 //哺乳动物类 24 class Mammalian :public Animal { 25 public: 26 Mammalian(); 27 ~Mammalian(); 28 virtual void speak() { 29 printf("哺乳动物在叫!"); 30 } 31 32 }; 33 34 Mammalian::Mammalian() { 35 } 36 37 Mammalian::~Mammalian() { 38 } 39 40 //老虎类 41 class Tiger :public Mammalian{ 42 public: 43 Tiger(); 44 ~Tiger(); 45 46 virtual void speak() { 47 printf("老虎在叫!"); 48 } 49 50 }; 51 52 Tiger::Tiger() { 53 } 54 55 Tiger::~Tiger() { 56 } 57 58 int main() { 59 Animal* mammalian = new Mammalian(); 60 Animal* tiger = new Tiger(); 61 62 Tiger* trueTiger1 = dynamic_cast<Tiger*>(tiger);//这是正确的 63 Tiger* trueTiger2 = dynamic_cast<Tiger*>(mammalian);//这是错误的 64 65 66 if (trueTiger1 = dynamic_cast<Tiger*>(tiger)) {//正确 67 trueTiger1->speak(); 68 } 69 70 if (trueTiger2 = dynamic_cast<Tiger*>(mammalian)){//trueTiger2指针为空,if条件为false,if里面的语句不执行 71 trueTiger2->speak(); 72 } 73 return 0; 74 }
75 //OUTPUT : 老虎在叫
D reinterpret_cast
3. 不要对数组使用多态
什么意思?
例如定义了一个基类指针的数组,可以用像 ' array[4]-> ' 这样 操作基类
然后用它操控派生类,就会出现问题,因为 ‘[ n ]' 是通过指针之间的距离(距离为 sizeof(element_In_array)* n ),那这个元素的大小(element_in_array)基类和派生类是不一定一样的,所以就有可能出问题。