我们知道在C++中基类的指针和引用可以指向派生类,因为这是安全的,派生类一定包含了基类
需要的所有的属性和方法,这是向上转换,我们同时还知道虚函数可以随着指针和引用指向的
对象不同而使用不同的方法,这是虚函数的自适应。
打个例子:
testb *p;
testc a(1,2);
testb b(1);
p可以指向派生类
p= &a;
p->show() 为派生类的testc::show();
p可以指向基类
p=&b;
p->show() 为基础类的testb::show();
因为show()虚函数,这样是可以完成。
但是我们考虑另外一种情况
testb *p;
testc a(1,2);
p= &a;
p->show2(); 是否能够按照我们预想的调用到testc::show2()呢
答案是否定的,因为show2()根本就不是虚函数.只有虚函数才有这样的自适应性,也就是根据指向对象的不同而调用合适的方法。
那么我们是否可以
(testc* )p;
这样处理呢,因为我们知道p指向是一定testc的派生类,我们将p指针转换后为testc*是安全的,这样处理是可以的。
这里谈到了安全,什么时候是不安全的呢?考虑如下情况:
testb *p;
testb b(1);
p= &b;
(testc* )p;
这就是不安全的,因为做强制转换将指向基础类 testb的指针转换为派生类testc指向那么void show2(void) const是不存在的。
当然这里我们可以人为判断,但是不是任何时候都可以这样,比如程序大了过后。我们需要一种方法来完成这样的判断工作,
那么引入了RTTI dynamic_cast
dynamic_cast<Type *>(pt)
成功pt转换为Type类型指针失败返回0及空指针。
最后演示一下用法头文件就是刚才给出的
输出:
dynamic check cast of q1 failed!!
test2:100
1
没有问题 testc * q1 = dynamic_cast < testc * > ( p ) ;
返回了一个空指针返回了 dynamic check cast of q1 failed!!
第二个
需要的所有的属性和方法,这是向上转换,我们同时还知道虚函数可以随着指针和引用指向的
对象不同而使用不同的方法,这是虚函数的自适应。
打个例子:
点击(此处)折叠或打开
- class testb
- {
- private:
- int a;
- public:
- testb(int ai){a=ai;}
- virtual void show(void) const
- {
- cout<<a<<endl;
- }
- virtual ~testb(){}
- };
-
-
- class testc:public testb
- {
- private:
- int b;
- public:
- testc(int ai,int bi):testb(ai),b(bi){}
- virtual void show(void) const
- {
- cout<<"test:"<<b<<endl;
- }
- void show2(void) const
- {
- cout<<"test2:"<<b<<endl;
- testb::show();
- }
- virtual ~testc(){}
- };
testb *p;
testc a(1,2);
testb b(1);
p可以指向派生类
p= &a;
p->show() 为派生类的testc::show();
p可以指向基类
p=&b;
p->show() 为基础类的testb::show();
因为show()虚函数,这样是可以完成。
但是我们考虑另外一种情况
testb *p;
testc a(1,2);
p= &a;
p->show2(); 是否能够按照我们预想的调用到testc::show2()呢
答案是否定的,因为show2()根本就不是虚函数.只有虚函数才有这样的自适应性,也就是根据指向对象的不同而调用合适的方法。
那么我们是否可以
(testc* )p;
这样处理呢,因为我们知道p指向是一定testc的派生类,我们将p指针转换后为testc*是安全的,这样处理是可以的。
这里谈到了安全,什么时候是不安全的呢?考虑如下情况:
testb *p;
testb b(1);
p= &b;
(testc* )p;
这就是不安全的,因为做强制转换将指向基础类 testb的指针转换为派生类testc指向那么void show2(void) const是不存在的。
当然这里我们可以人为判断,但是不是任何时候都可以这样,比如程序大了过后。我们需要一种方法来完成这样的判断工作,
那么引入了RTTI dynamic_cast
dynamic_cast<Type *>(pt)
成功pt转换为Type类型指针失败返回0及空指针。
最后演示一下用法头文件就是刚才给出的
点击(此处)折叠或打开
- #include<iostream>
- #include"dynamic_cast.h"
- using namespace std;
-
-
- int main(void)
- {
- testb *p;
- testb a(1);
- testc b(1,100);
- p=&a;
-
- testc *q1 = dynamic_cast<testc*>(p);
- if(!q1)
- {
- cout<<"dynamic check cast of q1 failed!!"<<endl;
- }
- else
- {
- q1->show2();
- }
-
- p=&b;
-
- testc *q2 = dynamic_cast<testc*>(p);
- if(!q2)
- {
- cout<<"dynamic check cast of q2 failed!!"<<endl;
- }
- else
- {
- q2->show2();
- }
-
-
- }
输出:
dynamic check cast of q1 failed!!
test2:100
1
没有问题 testc * q1 = dynamic_cast < testc * > ( p ) ;
返回了一个空指针返回了 dynamic check cast of q1 failed!!
第二个
testc
*
q2
=
dynamic_cast
<
testc
*
>
(
p
)
;
正常完成因为这个时候p指向是 testc b ( 1 , 100 ) ;
正常完成因为这个时候p指向是 testc b ( 1 , 100 ) ;