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  的用法,这里就不多说了,自己去查吧。

时间: 2024-11-26 08:55:06

C++类间转换之dynamic_cast的相关文章

C++标准转换运算符dynamic_cast

dynamic_cast <new_type> (expression) dynamic_cast运算符,应该算是四个里面最特殊的一个,因为它涉及到编译器的属性设置,而且牵扯到的面向对象的多态性跟程序运行时的状态也有关系,所以不能完全的使用传统的转换方式来替代.但是也因此它是最常用,最不可缺少的一个运算符. 与static_cast一样,dynamic_cast的转换也需要目标类型和源对象有一定的关系:继承关系. 更准确的说,dynamic_cast是用来检查两者是否有继承关系.因此该运算符实

C++ Primer 学习笔记_31_面向对象编程(2)--继承(二):继承与构造函数、派生类到基类的转换 、基类到派生类的转换

C++ Primer 学习笔记_31_面向对象编程(2)--继承(二):继承与构造函数.派生类到基类的转换 .基类到派生类的转换 一.不能自动继承的成员函数 构造函数 拷贝构造函数 析构函数 =运算符 二.继承与构造函数 基类的构造函数不被继承,派生类中需要声明自己的构造函数. 声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化调用基类构造函数完成(如果没有给出则默认调用默认构造函数). 派生类的构造函数需要给基类的构造函数传递参数 #include <iostream

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

很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中全部都按原样保留下来了,在派生类外可以调用基类的公用成员函数访问基类的私有成员.因此,公用派生类具有基类的全部功能,所有基类能够实现的功能, 公用派生类都能实现.而非公用派生类(私有或保护派生类)不能实现基类的全部功能(例如在派生类外不能调用基类的公用成员函数访问基类的私有成员).因此,只有公用派生

3.6 java基础总结①包装类,基本数据类型,String相互间转换

包装类,基本数据类型,String相互间转换 每个基本数据类型都有相对应的包装类型 包装类,基本数据类型,String相互间转换,这三者间的转换时很重要的: 一.String 转其他 String → 包装类型1.Integer(String str)调用包装类的带String参构造 String → 基本数据类型☆String → int调用包装类的parseInt方法 二.包装类转其他 → String调用包装类对象的ToString方法 → 基本类型①调用包装类的XXXValue方法包装类

iOS设计模式 - (2)UML类间关系精解

在正式讲设计模式之前, 介绍一下UML类图之间的关系还是非常有必要的, 由于一些教程, 书籍, 包含我之后的文章, 都会大量使用类图, 去描写叙述各个类之间的关系.这是一种非常直观, 简约的方式. 当然, 能力, 精力有限, 这里的UML的介绍也仅仅局限与几种常见的类间关系. 包含: 继承.实现.依赖.关联.聚合.组合 在次之前, 假设看不懂类图, 能够先看一下我之前写的一篇文章 : 具体解释八大UML类图符号的表示法 iOS - UML类间关系精解           by Colin丶 转载

类间的关系

类间关系可分为依赖.关联.聚合.组合和继承5种. 按照上述顺序,类间关系依次增强. 若类A的方法中仅仅使用了类B的对象,那么类A依赖于类B. 泛化/概化关系表示把几类对象类的公共属性和行为抽象成超类,然后其属性和方法被那些子类继承: 若类B除具有类A的全部特性外,类B还可定义新的特性以及置换类A的部分特性,则类B与类A具有泛化关系: 聚合关系表示一个较大的“整体”类包含一个或多个较小的“部分”类: 若类A的对象维持类B对象的引用或指针,并可与类C的对象共享相同的类B的对象,那么类A与类 B具有聚

Json与类对象转换

Json在js,jquery中可以直接使用,比如下串: { "from":"en" ,"to":"zh" ,"trans_result": [ {"src":"today","dst":"\u4eca\u5929"} ] } 可以直接使用data.from即可获取到"en". 但是在c#中不可以.要获取值,有

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

1. String类的转换功能 byte[] getBytes() char[] toCharArray() static String valueOf(char[] chs) static String valueOf(int i ) String toLowerCase() String toUpperCase() String concat(String str) 2. 案例: 1 package cn.itcast_05; 2 3 /* 4 * String的转换功能: 5 * byte

DataTable与实体类互相转换

/// <summary> /// DataTable与实体类互相转换 /// </summary> /// <typeparam name="T">实体类</typeparam> public class ModelHandler<T> where T : new() { #region DataTable转换成实体类 /// <summary> /// 填充对象列表:用DataSet的第一个表填充实体类 ///