腾讯微群加入QQ群

 找回密码
 加入我们

!connect_header_login!

!connect_header_login_tip!

搜索
查看: 925|回复: 0

[C/C++不常见语法特性]_[使用dynamic_cast 强制转换的优点]

[复制链接]
发表于 2016-8-23 15:03:46 | 显示全部楼层 |阅读模式


场景:

1. C++引入了dynamic_cast 这种类型识别的强制转换,对识别错误的程序是有好处的,建议能用的地方就用,它能在转换错误时返回0或抛出异常,比起C的旧强制转换

执行转换了不对类型依旧不会报错可靠些,因为这类错误如果发生了,其实很难找出来。


好处:

1.用在多态的子类情况下,父类不能提供处理接口,这时可以针对子类做特殊的处理。

2.dynamic_cast比另外3个cast优势就是会对转换进行检查,如果出错,会报错。


注意: [20160113更新]

1.  父类必须是带有virtual的生命的方法或构造函数才可以,即有vtable,不然dynamic_cast会编译报错.

错误	1	error C2683: “dynamic_cast”:“CWindow”不是多态类型	e:\work\sample\test_2005\test_2005\test_2005.cpp	37


补充一个知识点: 左值和右值 (摘录自C++ Primer 3rd)

// 变量和文字常量都有存储区并且有相关的类型,区别在于变量是可寻址的 addressable
// 对于每一个变量都有两个值与其相关联.

// 1.它的数据值存储在某个内存地址中有时这个值也被称为对象的右值rvalue
// 读做 are-value我们也可认为右值的意思是被读取的值read value,文字常量和变量都可被用作右值.

// 2.它的地址值——即存储数据值的那块内存的地址它有时被称为变量的左值lvalue 读作 ell-value
// 我们也可认为左值的意思是位置值location value,文字常量不能被用作左值.


#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>

using namespace std;

class Bill
{
public:

	virtual int GetBillNo()
	{
		return 0;
	}

	virtual time_t GetCreateDate()
	{
		time_t t;
		time(&t);
		return t;
	}

	virtual string GetBillName()
	{
		return string("Unknown.");
	}
};


class DebtBill : public Bill
{
public:
	virtual int GetBillNo()
	{
		return (int)this;
	}

	double GetDebtAmountDollar()
	{
		return  (int)this + 4.4;
	}

	virtual string GetBillName()
	{
		return string("DebtBill.");
	}
};

class OrderBill : public Bill
{
public:
	virtual int GetBillNo()
	{
		return (int)this;
	}

	virtual string GetBillName()
	{
		return string("OrderBill.");
	}
};


int main(int argc, char const *argv[])
{
	std::vector<Bill*> v;
	v.push_back(new DebtBill());
	v.push_back(new OrderBill());
	v.push_back(new OrderBill());
	v.push_back(new DebtBill());
	v.push_back(new OrderBill());

	for (size_t i = 0; i < v.size(); ++i)
	{
		Bill* bill = v;
		Bill& b2 = *bill;
		cout << "BillNo: " << bill->GetBillNo() 
		     << " BillName: " << bill->GetBillName() << endl;
		if (DebtBill* db = dynamic_cast<DebtBill*>(bill))
		{
			cout << "GetDebtAmountDollar: " << db->GetDebtAmountDollar() << endl;
		}
		//如果是左值,那么可以转换为类引用,如果出错会抛出异常.
		try
		{
			DebtBill& db2 = dynamic_cast<DebtBill&>(b2);
			cout << "GetDebtAmountDollar2: " << db2.GetDebtAmountDollar() << endl;
		}catch(std::bad_cast)
		{
			cout << "cast fail:" << endl;
		}
	}

	return 0;
}


输出:

BillNo: 3870632 BillName: DebtBill.
GetDebtAmountDollar: 3.87064e+006
GetDebtAmountDollar2: 3.87064e+006
BillNo: 3870680 BillName: OrderBill.
cast fail:
BillNo: 3870664 BillName: OrderBill.
cast fail:
BillNo: 3870696 BillName: DebtBill.
GetDebtAmountDollar: 3.8707e+006
GetDebtAmountDollar2: 3.8707e+006
BillNo: 3870736 BillName: OrderBill.
cast fail:

参考: 《C++ Primer 3rd Edition》



0
0

转自:http://blog.csdn.net/infoworld/article/details/24929943?locationNum=7
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

QQ|手机版|Archiver|小黑屋|一起疯|苦咖啡 ( 新ICP备12000197号  

GMT+8, 2018-6-25 17:31 , Processed in 0.105092 second(s), 12 queries , Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表