学习四种类型转换

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
请按任意键继续. . .

 

posted @ 2013-10-16 20:11  铁甲小宝  阅读(207)  评论(0编辑  收藏  举报