伙伴云客服论坛»论坛 S区 S软件开发 查看内容

0 评论

0 收藏

分享

四品种型转换cast,让你的C++代码更强大

目录

    引言1、static_cast
      1.1 根本类型转换1.2 类的上行转换(安全)1.3 类的下行转换(不安全)
    2、const_cast
      2.1 改变常量属性
    3、dynamic_cast
      3.1 类的上行转换(安全)3.2 类的下行转换(安全)
    4、reinterpret_cast
      4.1 非关联类型的转换
    总结


引言

C++11引入了四品种型转换接口,它们分别是static_cast、const_cast、dynamic_cast、reinterpret_cast。
为什么要使用这四种转换呢?
给出面向对象编程和面向对象设计的五个根本原则,SOLID原则。
    Single Responsibility Principle:单一职责原则Open Closed Principle:开闭原则Liskov Substitution Principle:里氏交换原则Law of Demeter:迪米特法则Interface Segregation Principle:接口隔离原则Dependence Inversion Principle:依赖倒置原则
这里不详细叙述五个根本原则,我们使用的cast接口和里氏交换原则有关。
里氏交换原则: “派生类(子类)对象可以在程式中替代其基类(超类)对象。” 以上内容并非利斯科夫的原文,而是译自罗伯特·马丁(Robert Martin)对原文的解读[1]。

1、static_cast


1.1 根本类型转换


1.2 类的上行转换(安全)

用于子类指针或引用转换为父类指针或引用。
  1. #include <iostream>
  2. using namespace std;
  3. class Base
  4. {
  5. public:
  6.     Base() {};
  7.     virtual void Show() { cout << "This is Base class"; }
  8. };
  9. class Derived :public Base
  10. {
  11. public:
  12.     Derived() {};
  13.     void Show() { cout << "This is Derived class"; }
  14. };
  15. int main()
  16. {
  17.     Derived* der = new Derived;
  18.     auto  Derived = static_cast<Base*> (der);
  19.     //向上转换不时是安全的
  20.     Derived->Show();
  21.     system("pause");
  22. }
复制代码
输出结果为
This is Derived class
存在虚函数重载,则父类的函数被隐藏不能使用。
由于使用dynamic_cast和static_cast方法会存在开销,则一般使用下列方法停止向上转换。
  1. class Base
  2. {
  3. public:
  4.     Base(){};
  5.     virtual void Show(){cout<<"This is Base class";}
  6. };
  7. class Derived:public Base
  8. {
  9. public:
  10.     Derived(){};
  11.     void Show(){cout<<"This is Derived class";}
  12. };
  13. int main()
  14. {
  15.     Base *base ;
  16.     Derived *der = new Derived;
  17.     //向上转换总是安全
  18.     base = der;
  19.     base->Show();
  20.     system("pause");
  21. }
复制代码
1.3 类的下行转换(不安全)

将父类指针、引用转换为子类指针、引用,但需要程序员自己检查,因而这种转换方式也不存在额外的开销。

2、const_cast


2.1 改变常量属性

    常量指针转化为非常量指针;常量引用转化为非常量引用;常量对象转化为非常量对象

3、dynamic_cast

该转换是运行时转换,其余都是编译时转换。主要用于安全的向下停止转换。同时当指针是智能指针时,使用dynamic_cast向下转换不能胜利,需使用dynamic_point_cast来停止转换。

3.1 类的上行转换(安全)

此处和static_cast是一样的,不再过多叙述。
  1. #include <iostream>
  2. using namespace std;
  3. class Base
  4. {
  5. public:
  6.     Base() {};
  7.     virtual void Show() { cout << "This is Base calss"; }
  8. };
  9. class Derived :public Base
  10. {
  11. public:
  12.     Derived() {};
  13.     void Show() { cout << "This is Derived class"; }
  14. };
  15. int main()
  16. {
  17.     Derived* der = new Derived;
  18.     auto  Derived = dynamic_cast<Base*> (der);
  19.     //向上转换不时是安全的
  20.     Derived->Show();
  21.     system("pause");
  22. }
复制代码
3.2 类的下行转换(安全)

因为有类型检查所以是安全的,但类型检查需要运行时类型信息,这个信息位于虚函数表中,所以必需要有虚函数,否则会转换失败。
在dynamic_cast转换中分为两种情况。
1、当基类指针指向派生对象时可以安全转换。
2、基类指针指向基类时会做检查,转换失败,返回结果0。
  1. #include <iostream>
  2. using namespace std;
  3. class Base
  4. {
  5. public:
  6.     Base() {};
  7.     virtual void Show() { cout << "This is Base class" << endl; }
  8. };
  9. class Derived :public Base
  10. {
  11. public:
  12.     Derived() {};
  13.     void Show() { cout << "This is Derived class" << endl; }
  14. };
  15. int main()
  16. {
  17.     //第一种情况
  18.     Base* base = new Derived;
  19.     Derived* der = dynamic_cast<Derived*>(base);
  20.     //基类指针指向派生类对象时可以安全转换
  21.     der->Show();
  22.     //第二种情况
  23.     Base *base1 = new Base;
  24.     if (Derived* der1 = dynamic_cast<Derived*> (base1))
  25.     {
  26.         der1->Show();
  27.     }
  28.     else
  29.     {
  30.         cout << "error!";
  31.     }
  32.     delete(base);
  33.     delete(base1);
  34.     system("pause");
  35. }
复制代码
This is Derived class
error!
引用则和指针不同,指针在C++11中存在空指针,而引用不存在空引用,会引发bad_cast异常。
  1. #include <iostream>
  2. using namespace std;
  3. class Base
  4. {
  5. public:
  6.     Base() {};
  7.     virtual void Show() { cout << "This is Base class" << endl; }
  8. };
  9. class Derived :public Base
  10. {
  11. public:
  12.     Derived() {};
  13.     void Show() { cout << "This is Derived class" << endl; }
  14. };
  15. int main()
  16. {
  17.     //基类引用子类
  18.     Derived b;
  19.     Base& base1 = b;
  20.     Derived& der1 = dynamic_cast<Derived&>(base1);
  21.     der1.Show();
  22.     //基类引用基类
  23.     Base a;
  24.     Base& base2 = a;
  25.     try
  26.     {
  27.         Derived& der2 = dynamic_cast<Derived&>(base2);
  28.     }
  29.     catch(bad_cast)
  30.     {
  31.         cout << "bad_cast error!!" << endl;
  32.     }
  33.     system("pause");
  34. }
复制代码
This is Derived class
bad_cast error!!

4、reinterpret_cast


4.1 非关联类型的转换

操作结果是一个指针到其他指针的二进制拷贝,没有类型检查。

总结

到此这篇关于C++11新特性之四品种型转换cast说明的文章就介绍到这了,更多相关C++11类型转换cast内容请搜索网站以前的文章或继续阅读下面的相关文章希望大家以后多多支持网站!

回复

举报 使用道具

全部回复
暂无回帖,快来参与回复吧
本版积分规则 高级模式
B Color Image Link Quote Code Smilies

战哥
注册会员
主题 21
回复 21
粉丝 0
|网站地图
快速回复 返回顶部 返回列表