《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指针

扫描二维码关注公众号,回复: 6259604 查看本文章

  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)基类和派生类是不一定一样的,所以就有可能出问题。

https://www.cnblogs.com/vectorli/p/5413470.html

猜你喜欢

转载自www.cnblogs.com/zhanghengyu/p/10896184.html