C++类间转换之dynamic_cast
当在C++的基类与派生类之间转换时,其多态性充分显现出来;
本次只讨论 dynamic_cast 的用法。
在查阅资料后发现百度百科关于 dynamic_cast (以及static_cast) 的代码说得十分清楚,摘抄如下(正所谓英雄不问出处):
#include"stdafx.h"
#include<iostream>
#include<stdlib.h>
using namespace std;
class Base
{
public:
virtual void f(){cout<<"Base::f"<<endl;}
void f1(){cout<<"Base::f1"<<endl;}
private:
double x;
double y;
};
class Derived:public Base
{
public:
virtual void f(){cout<<"Derived::f"<<endl;}
virtual void k(){cout<<"Derived::k"<<endl;}
private:
double z;
};
class Base1
{
public:
virtual void g(){cout<<"Base1::g"<<endl;}
void g1(){cout<<"Base1::g1"<<endl;}
};
class Derived1:public Base,public Base1
{
public:
virtual void f(){cout<<"Derived1::f"<<endl;}
virtual void h(){cout<<"Derived1::h"<<endl;}
};
void Test1()
{
//对于单继承,
//如果pD真的指向Derived,用dynamic_cast和static_cast效果相同
cout<<"-----------------Test1-----------------"<<endl;
Base* pD=new Derived;
Derived* pD1=dynamic_cast<Derived*>(pD);
pD1->f();
pD1->k();
pD1->f1();
Derived* pD2=static_cast<Derived*>(pD);
pD2->f();
pD2->k();
pD2->f1(); //但是如果pB不是真的指向Derived,则用dynamic_cast则返回NULL,能够更早的禁止error的发生,
//如果用static_cast虽然返回的不为NULL,但是运行时可能抛出exception。
/**/////Errorcode
//Base*pB=new Base();
//Derived*pD3=static_cast<Derived*>(pB);
//pD3->f();
//pD3->k();
//pD3->f1();
//Derived*pD4=dynamic_cast<Derived*>(pB);
//pD4->f();
//pD4->k();
//pD4->f1();
}
void Test2()
{
//对于多重继承,
//如果pD真的指向的是Derived1,使用dynamic_cast和static_cast都可以转化为Derived1,
//但是如果要转化为Base的兄弟类Base1,必须使用dynamic_cast,使用static_cast不能编译。
cout<<"-----------------Test2-----------------"<<endl;
Base* pD=new Derived1;
Derived1* pD1=dynamic_cast<Derived1*>(pD);
pD1->f();
pD1->h();
pD1->f1();
Base1* pB1=dynamic_cast<Base1*>(pD);
pB1->g();
Derived1* pD2=static_cast<Derived1*>(pD);
pD2->f();
pD1->h();
pD2->f1();
/**/////errorcannotcompiler
//Base1*pB2=static_cast<Base1*>(pD);
//pB2->g();
//当然对于pB不是真的指向Derived1,想要转化为Derived1或Base的兄弟类Base1,情况与Test1中的error情况相同。
} void Test3()
{
cout<<"-----------------Test3-----------------"<<endl;
Derived1* pD1=new Derived1;
Base1* pB1= pD1; //此时pB1可以访问g(),g1()
Base* pB = dynamic_cast<Base*>(pB1); //兄弟类之间的转换
pB->f(); //Base类f()被覆盖,访问的是Derive1类的f(),这一点有点像是“基类对象访问派生类的函数”
pB->f1();
} int _tmain(int argc,_TCHAR*argv[])
{
Test1();
Test2();
Test3();
system("Pause");
return 0 ;
}
其中Test3()所测试的功能Test2()中已有。
Test3()中基类对象指针pB在访问f()时,由于Base类f()被覆盖,所以访问的是Derive1类的f();
另外对于 static_cast 的用法,这里就不多说了,自己去查吧。
C++类间转换之dynamic_cast的更多相关文章
- C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast
关于强制类型转换的问题,许多书都讨论过,写的最具体的是C++之父的<C++的设计和演化>. 最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_c ...
- Java基础之8个基本类型及基本类型间转换
8种基本数据类型 Java语言有8种基本数据类型, 分别用于存储整数.浮点数.字符数据和布尔类型数据.需要注意的是: 现在所介绍的仅仅是基本数据类型,后续还会介绍很多非基本数据类型.基本数据类型如图 ...
- 详解C++中基类与派生类的转换以及虚基类
很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...
- DataTable与实体类互相转换
/// <summary> /// DataTable与实体类互相转换 /// </summary> /// <typeparam name="T"& ...
- UML(一) 类图及类间关系
原创文章,同步发自作者个人博客,http://www.jasongj.com/uml/class_diagram/ UML类图 UML类图介绍 在UML 2.*的13种图形中,类图是使用频率最高的UM ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- 图像二值化----otsu(最大类间方差法、大津算法)
最大类间方差法是由日本学者大津于1979年提出的,是一种自适应的阈值确定的方法,又叫大津 法,简称OTSU.它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间的类间方差越大,说明构成图像 ...
- 最大类间方差法(Otsu)
由Otsu(大津展之)于1978年提出的最大类间方差法,是引起较多关注的一种阈值选取方法.它是在判决分析或最小二乘原理的基础上推导出来的. 参考文献: [1] Otsu N. A threshold ...
- Java基础知识强化34:String类之String类的转换功能
1. String类的转换功能 String[] split(String regex)//将字符串变成字符串数组(字符串切割) byte[] getBytes()//将字符串变成字节数组 char[ ...
随机推荐
- xampp服务器搭建和使用
1.安装完XAMPP后会出现Apache端口被占用的问题,一下方法解决 错误信息如下: Error: Apache shutdown unexpectedly. 9:37:01 [Apache] T ...
- JAVA学习笔记--匿名内部类
匿名内部类,即没有名字的内部类. 我们在编写JAVA程序时,往往要创建很多类,类是可以被重复使用的.但有时,我们创建了一个类,却只需要使用该类一次,那么单独为其编写一个类就显得有些麻烦,这时可以使用匿 ...
- python怎么安装requests、beautifulsoup4等第三方库
零基础学习python最大的难题之一就是安装所有需要的软件,下面来简单介绍一下如何安装用pip安装requests.beautifulsoup4等第三方库: 方法/步骤 点击开始,在运行里 ...
- java-sun.misc.BASE64Decode AccessException
在使用sun.misc中base64类时,eclipse可能会报找不到Access异常 只需要修改一下访问方式即可,如下: 右键项目->属性->Javabulid path->jre ...
- SVN服务器搭建及客户端配置
为什么要使用SVN? 在程序的编写过程中,每个程序员都会负责开发一个或多个模块,且开发中会生成很多不同的版本, 这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subvers ...
- Python:Python的运行过程
1.Python是什么 和Java以及c#一样,Python也是一门基于虚拟机的语言.熟悉Java开发的人在命令行执行一个Java程序的过程通常如下: javac hello.java java he ...
- 使用C和C++实现“电梯”的区别
C 面向过程: 该电梯不允许未卜先知,故程序需逐条处理乘客请求并更新当前各变量状态. 如何获得最短时间:是否立即响应请求,计算出不同决策下的总时间,并进行比较,然后选择最短时间 ...
- 福大软工1816 - 404 Note Found选题报告
目录 NABCD分析引用 N(Need,需求): A(Approach,做法): B(Benefit,好处): C(Competitors,竞争): D(Delivery,交付): 初期 中期 个人贡 ...
- lintocde-247-线段树的查询 II
247-线段树的查询 II 对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现 ...
- 操作系统之实验二Step1-有序顺序表
实验二Step1-有序顺序表 专业:商业软件工程 班级:商软2班 姓名:甘佳萍 学号:201406114207 实验要求:初始化 输入数组元素个数. 输入n个数,排序输出. 存 ...