1 #include  < iostream >
 2 using   namespace  std;
 3
 4 class  Widget  {
 5    virtual void start() {
 6
 7    }

 8
 9}
;
10
11 class  SpecialWidget :  public  Widget  {
12
13}
;
14
15 void  update(SpecialWidget  * psw)
16 {
17    cout << "in update(SpecialWidget *)" << endl;
18}

19
20 void  update(SpecialWidget psw)
21 {
22    cout << "in update(SpecialWidget )" << endl;
23}

24
25 void  updateViaRef(SpecialWidget &  rsw)
26 {
27    cout << "in updateViaRef(SPecialWidget&)" << endl;
28}

29
30 int  main()
31 {
32    SpecialWidget sw;//sw是一个非const对象。
33    const SpecialWidget& csw = sw;//csw是sw的一个引用
34                                    //它是一个const对象
35    //update(&csw);//错误!不能传递一个const SpecialWidget*变量
36                   //给一个处理SpecialWidget*类型变量的参数
37
38
39    update(const_cast<SpecialWidget*>(&csw));
40                  //正确,csw的const被显示地转换掉
41                  //csw和sw两个变量值在update
42                  //函数中能被更新
43    update((SpecialWidget*)&csw);
44                  //同上,但用了一个更难的识别
45                  //的C风格的类型转换
46    Widget *pw = new SpecialWidget;
47    //update(pw);//错误!pw的类型是Widget*,但是
48             //update函数处理的是WidgetSpecialWidget*类型
49
50    //update(const_cast<SPecialWidget*>(pw));
51                //错误!const_cast仅能被用在影响
52                //constness or volatileness的地方上。
53                //不能用在向继承子类进行类型转换
54    update(dynamic_cast<SpecialWidget*>(pw));
55                //正确,传递给update函数一个指针
56                //是指向变量类型为SpecialWidget的pw的指针
57                //入股平pw确实指向一个一个对象
58                //否则传递过去的将是空指针
59    updateViaRef(sw);
60    //updateViaRef(csw);//错误。引用和指针一样,const实参不能赋给非const的形参的函数
61
62    updateViaRef(dynamic_cast<SpecialWidget&>(*pw));
63                //正确。传递给updateViaRef函数
64                //SpecialWidget pw指针,如果pw
65                //确实指向了某个对象
66                
67    update(csw);
68    update(sw);
69    return 0;
70}

71



注释掉错误行后的输出:
in update(SpecialWidget *)
in update(SpecialWidget *)
in update(SpecialWidget *)
in updateViaRef(SPecialWidget&)
in updateViaRef(SPecialWidget&)
in update(SpecialWidget )
in update(SpecialWidget )

如果不注释,编译会出现如下错误:
test.cpp: In function ‘int main()’:
test.cpp:35: error: invalid conversion from ‘const SpecialWidget*’ to ‘SpecialWidget*’
test.cpp:35: error:   initializing argument 1 of ‘void update(SpecialWidget*)’
test.cpp:47: error: invalid conversion from ‘Widget*’ to ‘SpecialWidget*’
test.cpp:47: error:   initializing argument 1 of ‘void update(SpecialWidget*)’
test.cpp:50: error: expected type-specifier before ‘SPecialWidget’
test.cpp:50: error: expected `>' before ‘SPecialWidget’
test.cpp:50: error: expected `(' before ‘SPecialWidget’
test.cpp:50: error: ‘SPecialWidget’ was not declared in this scope
test.cpp:50: error: expected primary-expression before ‘>’ token
test.cpp:60: error: invalid initialization of reference of type ‘SpecialWidget&’ from expression of type ‘const SpecialWidget’
test.cpp:25: error: in passing argument 1 of ‘void updateViaRef(SpecialWidget&)’


该例子学习自More Effective C++ Item M2:尽量使用 C++风格的类型转换
我自己增加的部分代码说明了const的指针和引用实参赋给非const的指针和引用不对,但const变量实参可以赋给非const变量形参。
如果注释掉
virtual void start {};
会编译如下错误
test.cpp: In function ‘int main()’:
test.cpp:54: error: cannot dynamic_cast ‘pw’ (of type ‘class Widget*’) to type ‘class SpecialWidget*’ (source type is not polymorphic)
test.cpp:62: error: cannot dynamic_cast ‘(Widget&)pw’ (of type ‘class Widget&’) to type ‘class SpecialWidget&’ (source type is not polymorphic)
因为    dynamic_casts 在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上(参见条款
M24)