C++类型父类与子类的转换--dynamic_cast

更新时间:2023-05-14 19:13:21 阅读: 评论:0

C++类型⽗类与⼦类的转换--dynamic_cast
徐长卿中药图片参考:/QG-whz/p/4517336.html
dynamic_cast主要⽤于“安全地向下转型”
dynamic_cast⽤于类继承层次间的指针或引⽤转换。主要还是⽤于执⾏“安全的向下转型(safe downcasting)”,也即是基类对象的指针或引⽤转换为同⼀继承层次的其他指针或引⽤。⾄于“先上转型”(即派⽣类指针或引⽤类型转换为其基类类型),本⾝就是安全的,尽管可以使⽤dynamic_cast进⾏转换,但这是没必要的,普通的转换已经可以达到⽬的,毕竟使⽤dynamic_cast是需要开销的。
#include <iostream>
using namespace std;
class Ba
{
public:
Ba() {};
virtual void Show() { cout << "This is Ba calss"; }
};
class Derived :public Ba
{
public:
Derived() {};
void Show() { cout << "This is Derived class"; }
void Dfun() { cout << "Dfun"; }
};
int main11()
{
Ba *ba;
鼻窦炎怎么治疗Derived *der = new Derived;
//ba = dynamic_cast<Ba*>(der); //正确,但不必要。
ba = der; //先上转换总是安全的
ba->Show();  // This is Derived class      ⼦类转⽗类,安全,且转换后,还是调⽤⼦类的虚函数,
//ba->Dfun(); //ERR: Dfun不是Ba的成员⼦类转⽗类,安全,但是转换后,不能再使⽤⼦类的⾮虚函数,
return 0;
}
dynamic_cast与继承层次的指针
对于“向下转型”有两种情况。⼀种是基类指针所指对象是派⽣类类型的,这种转换是安全的;另⼀种是基类指针所指对象为基类类型,在这种情况下dynamic_cast在运⾏时做检查,转换失败,返回结果为0;
#include <iostream>
using namespace std;
class Ba
{
public:
Ba() {};
virtual void Show() { cout << "This is Ba calss"<<endl; }
};
class Derived :public Ba文殊菩萨的故事
{
public:
Derived() {};
virtual void Show() { cout << "This is Derived class"<<endl; }
void Dfun() { cout << "Dfun"<<endl; }
char name[10];
};
int main222()
{
//场景⼀:
Ba *ba = new Ba;
/
/Derived *der = ba; //error C2440 : “初始化”: ⽆法从“Ba * ”转换为“Derived *”
Derived *der = dynamic_cast<Derived*>(ba);  //执⾏完后  der是空指针,所以这个转换时⽆意义的
保护的英语//der->Show();  //编译没问题,运⾏就会报  der是nulptr的段错误。
der->Dfun(); //OK  实际上同下⼀条语句
//((Derived*)(0))->Dfun(); //OK
家贼//cout<<sizeof(((Derived*)(0))->name)<<endl;  // OK  10
//正确使⽤场景:⽗类指针指向⼦类对象,需要使⽤⼦类对象的⾮虚接⼝时
Ba *pB = new Derived;
//Derived *pD = pB; //“初始化”: ⽆法从“Ba * ”转换为“Derived *”  解析:多态是运⾏时才有的,
Derived *pD = dynamic_cast<Derived*>(pB);
pD->Dfun();  // 如果直接使⽤ pB->Dfun(); 就会报错,error C2039: 'Dfun' : is not a member of 'Ba'
cout << sizeof(pD->name)<<endl;  // OK  10
pD->Show();
return 0;
}
dynamic_cast和引⽤类型
在前⾯的例⼦中,使⽤了dynamic_cast将基类指针转换为派⽣类指针,也可以使⽤dynamic_cast将基类引⽤转换为派⽣类引⽤。
同样的,引⽤的向上转换总是安全的:
Derived c;
Derived & der2= c;
Ba & ba2= dynamic_cast<Ba&>(der2);//向上转换,安全
五猖会读后感ba2.Show();
  所以,在引⽤上,dynamic_cast依旧是常⽤于“安全的向下转型”。与指针⼀样,引⽤的向下转型也可以分为两种情况,与指针不同的是,并不存在空引⽤,所以引⽤的dynamic_cast检测失败时会抛出⼀个bad_cast异常:
int main()
{
//第⼀种情况,转换成功
Derived b ;
Ba &ba1= b;
Derived &der1 = dynamic_cast<Derived&>(ba1);
cout<<"第⼀种情况:";
der1.Show();
cout<<endl;
//第⼆种情况
Ba a ;
Ba &ba = a ;
cout<<"第⼆种情况:";
try{
Derived & der = dynamic_cast<Derived&>(ba);
}
catch(bad_cast)
{
cout<<"转化失败,抛出bad_cast异常"<<endl;
}
system("pau");
淀粉与面粉的区别}
运⾏结果:
使⽤dynamic_cast转换的Ba类⾄少带有⼀个虚函数
当⼀个类中拥有⾄少⼀个虚函数的时候,编译器会为该类构建出⼀个虚函数表(virtual method table),虚函数表记录了虚函数的地址。如果该类派⽣了其他⼦类,且⼦类定义并实现了基类的虚函数,那么虚函数表会将该函数指向新的地址。虚表是C++多态实现的⼀个重要⼿段,也是dynamic_cast操作符转换能够进⾏的前提条件。当类没有虚函数表的时候(也即⼀个虚函数都没有定义),dynamic_cast⽆法使⽤RTTI,不能通过编译,报错:error C2683: “dynamic_cast”:“Ba”不是多态类型。
  当然,虚函数表的建⽴对效率是有⼀定影响的,构建虚函数表、由表查询函数都需要时间和空间上
腊肉的腌制的消耗。所以,除了必须声明virtual(对于⼀个多态基类⽽⾔),不要轻易使⽤virtual函数。对于虚函数的进⼀步了解,可以查看《Effective C++》

本文发布于:2023-05-14 19:13:21,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/631058.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   指针   转换   基类   失败   对象   图片   需要
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图