C++类型转化分析:动态态转换->dynamic_cast
2013-08-18 18:05
501 查看
dynamic_cast
static_cast可以实现子类到基类的安全转换,但是不能实现基类到子类的安全转换,那么如果想实现基类到子类的安全转换应该怎么处理呢?嗯是用dynamic_cast类型转换:
注意:
上行转换(子类到基类)是安全的,并且static_cast dynamic_cast是等效的
下行转换(基类到子类)static_cast转换是不安全的但是dynamic_cast转换是安全的
dynamic_cast被用来执行从基类到子类的安全转换,转换的类类型(基类)必须有虚函数,否则不能使用dynamic_cast
dynamic_cast<type-id>(expression)
如果type-id是void*类型,那么是expression类型。
如果type-id是非void*类型,那么运行时检查指向 expression 的对象能否转换为指向 type-id 类型的对象。
dynamic_cast指针例子:
class employee{
public:
virtual int salary();
};
class manager:public employee{
public:
int salary();
};
class programmer:public employee{
public:
int salary();
int bonus();
};
mytest(employee* pe){
//如果pe指向的是programmer类型的对象,则转换成功。否则,失败,结果为0。
programmer *pm = dynamic_cast<programmer*>(pe);
if(pm){//在使用pm之前必须使用if语句来判断是否转换成功
//可以用pm调用programmer::bonus()
}
else{
//只能使用employee的成员的虚函数。
}
}
因为存在空指针,所以mytest中可以使用if(pm)来判断转换是否有效。但是不存在空引用,因此不能比较dynamic_cast的结果是否为0来判断引用转换成功与否,但是会抛出bad_cast的异常。
mytest(employee& re){
try{
programmer& em = dynamic_cast<programmer&>(re);
//用em调用bonus;
}
catch(std:: bad_cast)
{
//使用employee的成员函数
}
}
例子总结:
1:
class A{};
class B{};
void func(){
A* pa=new A;
B* pb=new B;
void* pv=dynamic_cast<void*>(pa);
//pv就是一个A类型的对象了
......
pv=dynamic_cast<void*>(pb);
//pv就是一个B类型的对象了
......
}
2:
class B{};
class D:public B{};
void func(){
B* pb=new D;
B* pb2=new B;
D* pd=dynamic_cast<D*>(pb);//ok 转换成功,pd是一个指向D的指针
D* pd2=dynamic_cast<D*>(pb2);//转换失败但是编译通过,因为pd2指向的是null
}
为什么基类向子类转换会转换失败呢?因为基类向子类转换有可能会出现二义性。
另外:
dynamic_cast还支持交叉转换(cross cast)。如下代码所示。
class A{
public:
int m_iNum;
virtual void f(){}
};
class B:public A{
};
class D:public A{
};
void foo(){
B *pb = new B;
pb->m_iNum = 100;
D *pd1 = static_cast<D*>(pb); //compile error
D *pd2 = dynamic_cast<D*>(pb); //pd2 is NULL
delete pb;
}
在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。
static_cast可以实现子类到基类的安全转换,但是不能实现基类到子类的安全转换,那么如果想实现基类到子类的安全转换应该怎么处理呢?嗯是用dynamic_cast类型转换:
注意:
上行转换(子类到基类)是安全的,并且static_cast dynamic_cast是等效的
下行转换(基类到子类)static_cast转换是不安全的但是dynamic_cast转换是安全的
dynamic_cast被用来执行从基类到子类的安全转换,转换的类类型(基类)必须有虚函数,否则不能使用dynamic_cast
dynamic_cast<type-id>(expression)
如果type-id是void*类型,那么是expression类型。
如果type-id是非void*类型,那么运行时检查指向 expression 的对象能否转换为指向 type-id 类型的对象。
dynamic_cast指针例子:
class employee{
public:
virtual int salary();
};
class manager:public employee{
public:
int salary();
};
class programmer:public employee{
public:
int salary();
int bonus();
};
mytest(employee* pe){
//如果pe指向的是programmer类型的对象,则转换成功。否则,失败,结果为0。
programmer *pm = dynamic_cast<programmer*>(pe);
if(pm){//在使用pm之前必须使用if语句来判断是否转换成功
//可以用pm调用programmer::bonus()
}
else{
//只能使用employee的成员的虚函数。
}
}
因为存在空指针,所以mytest中可以使用if(pm)来判断转换是否有效。但是不存在空引用,因此不能比较dynamic_cast的结果是否为0来判断引用转换成功与否,但是会抛出bad_cast的异常。
mytest(employee& re){
try{
programmer& em = dynamic_cast<programmer&>(re);
//用em调用bonus;
}
catch(std:: bad_cast)
{
//使用employee的成员函数
}
}
例子总结:
1:
class A{};
class B{};
void func(){
A* pa=new A;
B* pb=new B;
void* pv=dynamic_cast<void*>(pa);
//pv就是一个A类型的对象了
......
pv=dynamic_cast<void*>(pb);
//pv就是一个B类型的对象了
......
}
2:
class B{};
class D:public B{};
void func(){
B* pb=new D;
B* pb2=new B;
D* pd=dynamic_cast<D*>(pb);//ok 转换成功,pd是一个指向D的指针
D* pd2=dynamic_cast<D*>(pb2);//转换失败但是编译通过,因为pd2指向的是null
}
为什么基类向子类转换会转换失败呢?因为基类向子类转换有可能会出现二义性。
另外:
dynamic_cast还支持交叉转换(cross cast)。如下代码所示。
class A{
public:
int m_iNum;
virtual void f(){}
};
class B:public A{
};
class D:public A{
};
void foo(){
B *pb = new B;
pb->m_iNum = 100;
D *pd1 = static_cast<D*>(pb); //compile error
D *pd2 = dynamic_cast<D*>(pb); //pd2 is NULL
delete pb;
}
在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。
相关文章推荐
- C++类型转化分析:静态转换->static_cast
- C++类型转化分析:强制转换->const_cast转换
- C++类型转化分析:强制转换,动态转换,静态转换等。
- C++类型转换运算符: static_cast<>,reinterpret_cast<>,dynamic_cast<>, const_cast<>
- <转>标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
- 关于c++ 强制转换类型运算符 static_cast、dynamic_cast、reinterpret_和const_cast
- C++类型转换运算符 static_cast,dynamic_cast,reinterpret_cast,const_cast
- C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
- 使用标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。(转)
- 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
- 使用标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
- 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast(转载)
- c++类型转换static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较,显示转换,隐式转换
- 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast(转载)
- C++类型转换:C++风格: static_cast、dynamic_cast、reinterpre
- C++的类型转换运算符(一)——static_cast 与 dynamic_cast
- C++类型转化:static_cast,reinterpret_cast,dynamic_cast,const_cast
- 使用标准C++的类型转换符--static_cast、dynamic_cast、reinterpret_cast、const_cast
- C++的类型转换static_cast、dynamic_cast、reinterpret_cast
- 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast(转载)