zoukankan      html  css  js  c++  java
  • 学习四种类型转换

    C++的四种类型转换的练习代码,该说的都在注释中,培养大家看代码的耐心~~

    代码:

      1 #include <iostream>
      2 #include <stdlib.h>
      3 
      4 /**
      5 * @author:zanzan101
      6 */
      7 
      8 using namespace std;
      9 
     10 class A
     11 {
     12 private:
     13     int data;
     14 
     15     // 小知识:引用可以出现在类中,它的初始化和const类型类似,都是必须放到初始化列表中
     16     int& ref;
     17 public:
     18 
     19     // 小知识:初始化列表中初始化的顺序,根据类中变量定义的顺序而定,与参数列表中的顺序无关
     20     A():data(1), ref(data){}
     21     int doSomething(){
     22         cout<< "A do something ..." <<endl;
     23         return 123;
     24     }
     25     void toString()
     26     {
     27         cout<< "A" <<endl;
     28     }
     29 };
     30 class B : public A
     31 {
     32 public:
     33     // 当仅仅返回值类型不同时
     34     // 视为无多态行为的重写
     35     // 和下面的toString函数类似
     36     void doSomething(){
     37         cout<< "B do something ..." <<endl;
     38     }
     39     // 非虚函数的重写合法,但是无法触发多态行为
     40     // 触发多态行为的唯一途径是父类的指针或者引用调用子类实现的虚函数
     41     void toString()
     42     {
     43         cout<< "B" <<endl;
     44     }
     45 };
     46 
     47 class C
     48 {
     49 private:
     50     int data;
     51 public:
     52     virtual void doSomething(){
     53         cout<< "C do something ..." <<endl;
     54     }
     55 };
     56 class D : public C
     57 {
     58 public:
     59     // 错误演示:
     60     // error C2555: “D::doSomething”: 重写虚函数返回类型有差异,且不是来自“C::doSomething”的协变
     61 //     virtual int doSomething(){
     62 //         cout<< "B do something ..." <<endl;
     63 //     }
     64 
     65     // 正确方法:
     66     virtual void doSomething(){
     67         cout<< "D do something ..." <<endl;
     68     }
     69 };
     70 
     71 void func_void()
     72 {
     73     cout<< "func_void" << endl;
     74     return;
     75 }
     76 
     77 int func_int()
     78 {
     79     cout<< "func_int" << endl;
     80     return 1;
     81 }
     82 
     83 void do_func(void(*ptr_func)())
     84 {
     85     ptr_func();
     86 }
     87 
     88 int main()
     89 {
     90     // static_cast        如同普通转型一样
     91     
     92     // const_cast        去掉常量性
     93     
     94     // dynamic_cast        向下转换指针类型,前提是该指针或引用必须确实是指向的子类对象,否则返回NULL,
     95     //                    即最终结果不能出现子类指针指向父类对象的情况
     96 
     97     // reinterpret_cast    转换函数指针
     98 
     99     int num = 0;
    100     char ch = 'A';
    101     num = static_cast<int>(ch);
    102     cout<<"num = " << num << endl;
    103 
    104     const int c_num = 1;
    105 
    106     // 错误演示:
    107 //    c_num = 2;
    108 
    109     // 错误演示:
    110     // const_cast 只能处理指针或者引用
    111 //    int nc_num = const_cast<int>(c_num);
    112 
    113     const int * p = &c_num;
    114     int* q = const_cast<int*>(p);    
    115     *q = 2;    
    116     // 如果这个对象处于常量区,即使做了转型,也是无法修改
    117     cout<<"c_num = " << c_num << endl;
    118 
    119     p = &num;
    120     
    121     // 错误演示:
    122     // 对const类型指针所指对象赋值
    123 //    *p = 2;
    124     
    125     // 正确方法:
    126     q = const_cast<int*>(p);
    127     *q = 2;
    128     // 如果这个对象不处于常量区,则转型之后可以修改
    129     cout<<"num = " << num << endl;
    130 
    131     A a;
    132     B b;
    133     a.doSomething();
    134 
    135     // 错误演示
    136     //int res = b.doSomething();
    137     // 看看有返回值对重载的影响
    138     //cout<< "res = " << res << endl;
    139 
    140     // 错误演示:
    141     // error C2440: “初始化”: 无法从“A *”转换为“B *”
    142 //    B* ptr = &a;
    143 
    144     // 正确方法:
    145     // 向上转型,天生就可以转,但是向下转型必须用dynamic_cast
    146     A* ptr1 = &b;
    147     ptr1->doSomething();
    148 
    149     // 错误演示:
    150     // error C2440: “初始化”: 无法从“A *”转换为“B *”
    151     // 这里很有意思的是:ptr1明明指向的是B的对象,却不能赋值给ptr2,因此,dynamic_cast就有了用武之地
    152 //    B* ptr2 = ptr1;
    153 
    154     // 错误演示:
    155     // error C2683: “dynamic_cast”:“A”不是多态类型
    156     // 用了dynamic_cast,却依然出错,因为A类没有虚函数,即:没有多态行为
    157 //    B* ptr2 = dynamic_cast<B*>(ptr1);
    158 
    159     C c;
    160     D d;
    161     c.doSomething();
    162     d.doSomething();
    163     C* ptr3 = &d;
    164     D* ptr4 = dynamic_cast<D*>(ptr3);
    165     ptr3->doSomething();
    166     ptr4->doSomething();
    167 
    168     // 错误演示:
    169     // 违背“该指针或引用必须确实是指向的子类对象”的前提
    170     D* ptr5 = dynamic_cast<D*>(&c);
    171     if(!ptr5)
    172         cout<< "ptr5 is NULL...dynamic_cast failed!" << endl;
    173 
    174     // 正常调用
    175     do_func(func_void);
    176 
    177     // 错误调用
    178     // error C2664: “do_func”: 不能将参数 1 从“int (__cdecl *)(void)”转换为“void (__cdecl *)(void)”
    179 //    do_func(func_int);
    180 
    181     // 正确方法:
    182     // 使用reinterpret_cast
    183     do_func(reinterpret_cast<void(*)()>(func_int));
    184 
    185     system("pause");
    186     
    187     return 0;
    188 }

    输出结果:

    num = 65
    c_num = 1
    num = 2
    A do something ...
    A do something ...
    C do something ...
    D do something ...
    D do something ...
    D do something ...
    ptr5 is NULL...dynamic_cast failed!
    func_void
    func_int
    请按任意键继续. . .
  • 相关阅读:
    有哪些带汉字的 LOGO 或者图标设计得很出色?
    从初级晋级高级UI设计师学习路线+全套视频
    UI常见面试题-整体素养篇
    PS精修电影胶片调色特效[附素材及方法]
    全链路UI、UE设计学习路线+视频教程完整版
    网页设计之栅格系统及应用
    移动端APP产品设计结构及专业术语
    九十分钟极速入门Linux——Linux Guide for Developments 学习笔记
    PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
    数据结构第三部分:树与树的表示、二叉树及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树、集合及其运算
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3372850.html
Copyright © 2011-2022 走看看