当在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的更多相关文章

  1. C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast

    关于强制类型转换的问题,许多书都讨论过,写的最具体的是C++之父的<C++的设计和演化>. 最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_c ...

  2. Java基础之8个基本类型及基本类型间转换

    8种基本数据类型 Java语言有8种基本数据类型, 分别用于存储整数.浮点数.字符数据和布尔类型数据.需要注意的是: 现在所介绍的仅仅是基本数据类型,后续还会介绍很多非基本数据类型.基本数据类型如图 ...

  3. 详解C++中基类与派生类的转换以及虚基类

    很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...

  4. DataTable与实体类互相转换

    /// <summary> /// DataTable与实体类互相转换 /// </summary> /// <typeparam name="T"& ...

  5. UML(一) 类图及类间关系

    原创文章,同步发自作者个人博客,http://www.jasongj.com/uml/class_diagram/ UML类图 UML类图介绍 在UML 2.*的13种图形中,类图是使用频率最高的UM ...

  6. 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)

    [源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...

  7. 图像二值化----otsu(最大类间方差法、大津算法)

    最大类间方差法是由日本学者大津于1979年提出的,是一种自适应的阈值确定的方法,又叫大津 法,简称OTSU.它是按图像的灰度特性,将图像分成背景和目标2部分.背景和目标之间的类间方差越大,说明构成图像 ...

  8. 最大类间方差法(Otsu)

    由Otsu(大津展之)于1978年提出的最大类间方差法,是引起较多关注的一种阈值选取方法.它是在判决分析或最小二乘原理的基础上推导出来的. 参考文献: [1] Otsu N. A threshold ...

  9. Java基础知识强化34:String类之String类的转换功能

    1. String类的转换功能 String[] split(String regex)//将字符串变成字符串数组(字符串切割) byte[] getBytes()//将字符串变成字节数组 char[ ...

随机推荐

  1. xampp服务器搭建和使用

    1.安装完XAMPP后会出现Apache端口被占用的问题,一下方法解决 错误信息如下: Error: Apache shutdown unexpectedly. 9:37:01  [Apache] T ...

  2. JAVA学习笔记--匿名内部类

    匿名内部类,即没有名字的内部类. 我们在编写JAVA程序时,往往要创建很多类,类是可以被重复使用的.但有时,我们创建了一个类,却只需要使用该类一次,那么单独为其编写一个类就显得有些麻烦,这时可以使用匿 ...

  3. python怎么安装requests、beautifulsoup4等第三方库

    零基础学习python最大的难题之一就是安装所有需要的软件,下面来简单介绍一下如何安装用pip安装requests.beautifulsoup4等第三方库:   方法/步骤     点击开始,在运行里 ...

  4. java-sun.misc.BASE64Decode AccessException

    在使用sun.misc中base64类时,eclipse可能会报找不到Access异常 只需要修改一下访问方式即可,如下: 右键项目->属性->Javabulid path->jre ...

  5. SVN服务器搭建及客户端配置

    为什么要使用SVN? 在程序的编写过程中,每个程序员都会负责开发一个或多个模块,且开发中会生成很多不同的版本, 这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subvers ...

  6. Python:Python的运行过程

    1.Python是什么 和Java以及c#一样,Python也是一门基于虚拟机的语言.熟悉Java开发的人在命令行执行一个Java程序的过程通常如下: javac hello.java java he ...

  7. 使用C和C++实现“电梯”的区别

    C 面向过程:       该电梯不允许未卜先知,故程序需逐条处理乘客请求并更新当前各变量状态.       如何获得最短时间:是否立即响应请求,计算出不同决策下的总时间,并进行比较,然后选择最短时间 ...

  8. 福大软工1816 - 404 Note Found选题报告

    目录 NABCD分析引用 N(Need,需求): A(Approach,做法): B(Benefit,好处): C(Competitors,竞争): D(Delivery,交付): 初期 中期 个人贡 ...

  9. lintocde-247-线段树的查询 II

    247-线段树的查询 II 对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现 ...

  10. 操作系统之实验二Step1-有序顺序表

    实验二Step1-有序顺序表 专业:商业软件工程     班级:商软2班     姓名:甘佳萍     学号:201406114207 实验要求:初始化 输入数组元素个数. 输入n个数,排序输出. 存 ...