C++ dynamic_cast的使用

C++11中引入了一些新的类型转换操作符,我们来看看dynamic_cast的使用。
首先,让我们考虑一下:在什么场景下我们希望使用dynamic_cast呢?

#include <iostream>

class Base
{
public:
	virtual void print()
	{
		std::cout << "Base print" << std::endl;
	}

	void work()
	{
		std::cout << "Base do work..." << std::endl;
	}
};

class Derived : public Base
{
public:
	virtual void print()
	{
		std::cout << "Derived print!" << std::endl;
	}
	void work()
	{
		std::cout << "Derived do work..." << std::endl;
	}
};

int main()
{
	Base* pBase = new Derived();
	pBase->print();
	pBase->work();
	
	getchar();
	return 0;
}

运行结果:

Derived print!
Base do work...

分析结果:print()是虚函数,在运行时的类型来决定运行结果;而work()函数不是虚函数,只是类的普通成员函数,在编译期间决定。所以调用的Base::work()函数。

如果我们希望通过指针调用Derived::work(),该怎么做呢?
使用dynamic_cast

Derived* pDerived = dynamic_cast<Derived*>(pBase);

语法

dynamic_cast < 新类型 > ( 表达式 )	

若转型成功,则 dynamic_cast 返回 新类型 类型的值。若转型失败且 新类型 是指针类型,则它返回该类型的空指针若转型失败且 新类型 是引用类型,则它抛出与类型 std::bad_cast 的处理块匹配的异常

为了理解官方文档这段话,我写了下面的代码,在刚才的代码上修改,只修改了main函数中的内容:

int main()
{
	Base* pBase = new Derived();
	pBase->print();
	pBase->work();
	 
	Derived* pDerived = dynamic_cast<Derived*>(pBase); //向下转换成功,成功返回Derived*
	if (pDerived != nullptr)
	{
		pDerived->print();
		pDerived->work();
	}

	Base *pRealBase = new Base();
	pDerived = dynamic_cast<Derived*>(pRealBase); //向下转换失败,返回nullptr指针
	if (pDerived != nullptr)
	{
		pDerived->print();
		pDerived->work();
	}

	Base base;
	Base& refBase = base;
	try
	{
		Derived refDerived = dynamic_cast<Derived&>(refBase);
	}
	catch (const std::exception& e)
	{
		std::cout << "first try failed, reason: " << e.what() << std::endl;
	}
	
	Derived derived;
	Base& refBaseNew = derived;
	try
	{
		Derived refDerived = dynamic_cast<Derived&>(refBaseNew);
	}
	catch (const std::exception& e)
	{
		std::cout << "second try failed: reason: " << e.what() << std::endl;
	}

	getchar();
	return 0;
}

运行结果:

Derived print!
Base do work...
Derived print!
Derived do work...
first try failed, reason: Bad dynamic_cast!

小结
dynamic_cast < new_type > ( expression )

在执行向下类型转换(基类向子类转换,叫“向下类型转换”),如果expression实际指向的类型与new_type一致,转换才能成功,否则转换失败。

dynamic_cast存在的问题
dynamic_cast最大的问题在于效率,特别是继承体系特别深时。可以尝试用static_cast来替代dynamic_cast的使用。

对于效率问题,这篇博文里讲的比较好:https://blog.csdn.net/debugconsole/article/details/9379627

为什么说不要使用 dynamic_cast,需要运行时确定类型信息,说明设计有缺陷?

参考:https://blog.csdn.net/u011333734/article/details/81329523

http://www.luyixian.cn/news_show_19011.aspx

https://blog.csdn.net/daizhiyan1/article/details/82912399

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值