https://img-blog.csdnimg.cn/32db9ce43ef64316a2e37a31f4cee033.gif
编程小鱼酱yu612.com,点击前往

C++ dynamic_cast 进行强转

公司的项目当中 禁止使用了dynamic_cast,进行强制类型转换。


#pragma once

class ElementBase
{
public:
	ElementBase(void){};
	~ElementBase(void){};

	void show()
	{
		printf("Base");
	}
};

#pragma once
#include "ElementBase.h"

class routeElement :
	public ElementBase
{
public:
	routeElement(void){};
	~routeElement(void){};

	void haha()
	{
		printf("00000");
	}
};


// aaaa.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "ElementBase.h"
#include "routeElement.h"

int _tmain(int argc, _TCHAR* argv[])
{	

	ElementBase *elem;
	routeElement *son = new routeElement;
	

	elem =son;

	elem->show();

	((routeElement*)elem)->haha(); //没有进行dynamic_cast 进行强转


	return 0;
}


强转会抛出异常,而我们公司的框架决定,所以不使用这个关键字


下面为查找到的资料:

场景:

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

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


好处:

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

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


注意: [20160113更新]

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

  1. 错误  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,文字常量不能被用作左值.


  1. #include <stdlib.h>  
  2. #include <assert.h>  
  3. #include <time.h>  
  4. #include <iostream>  
  5. #include <string>  
  6. #include <vector>  
  7. #include <typeinfo>  
  8.   
  9. using namespace std;  
  10.   
  11. class Bill  
  12. {  
  13. public:  
  14.   
  15.     virtual int GetBillNo()  
  16.     {  
  17.         return 0;  
  18.     }  
  19.   
  20.     virtual time_t GetCreateDate()  
  21.     {  
  22.         time_t t;  
  23.         time(&t);  
  24.         return t;  
  25.     }  
  26.   
  27.     virtual string GetBillName()  
  28.     {  
  29.         return string("Unknown.");  
  30.     }  
  31. };  
  32.   
  33.   
  34. class DebtBill : public Bill  
  35. {  
  36. public:  
  37.     virtual int GetBillNo()  
  38.     {  
  39.         return (int)this;  
  40.     }  
  41.   
  42.     double GetDebtAmountDollar()  
  43.     {  
  44.         return  (int)this + 4.4;  
  45.     }  
  46.   
  47.     virtual string GetBillName()  
  48.     {  
  49.         return string("DebtBill.");  
  50.     }  
  51. };  
  52.   
  53. class OrderBill : public Bill  
  54. {  
  55. public:  
  56.     virtual int GetBillNo()  
  57.     {  
  58.         return (int)this;  
  59.     }  
  60.   
  61.     virtual string GetBillName()  
  62.     {  
  63.         return string("OrderBill.");  
  64.     }  
  65. };  
  66.   
  67.   
  68. int main(int argc, char const *argv[])  
  69. {  
  70.     std::vector<Bill*> v;  
  71.     v.push_back(new DebtBill());  
  72.     v.push_back(new OrderBill());  
  73.     v.push_back(new OrderBill());  
  74.     v.push_back(new DebtBill());  
  75.     v.push_back(new OrderBill());  
  76.   
  77.     for (size_t i = 0; i < v.size(); ++i)  
  78.     {  
  79.         Bill* bill = v[i];  
  80.         Bill& b2 = *bill;  
  81.         cout << "BillNo: " << bill->GetBillNo()   
  82.              << " BillName: " << bill->GetBillName() << endl;  
  83.         if (DebtBill* db = dynamic_cast<DebtBill*>(bill))  
  84.         {  
  85.             cout << "GetDebtAmountDollar: " << db->GetDebtAmountDollar() << endl;  
  86.         }  
  87.         //如果是左值,那么可以转换为类引用,如果出错会抛出异常.  
  88.         try  
  89.         {  
  90.             DebtBill& db2 = dynamic_cast<DebtBill&>(b2);  
  91.             cout << "GetDebtAmountDollar2: " << db2.GetDebtAmountDollar() << endl;  
  92.         }catch(std::bad_cast)  
  93.         {  
  94.             cout << "cast fail:" << endl;  
  95.         }  
  96.     }  
  97.   
  98.     return 0;  
  99. }  


输出:

  1. BillNo: 3870632 BillName: DebtBill.  
  2. GetDebtAmountDollar: 3.87064e+006  
  3. GetDebtAmountDollar2: 3.87064e+006  
  4. BillNo: 3870680 BillName: OrderBill.  
  5. cast fail:  
  6. BillNo: 3870664 BillName: OrderBill.  
  7. cast fail:  
  8. BillNo: 3870696 BillName: DebtBill.  
  9. GetDebtAmountDollar: 3.8707e+006  
  10. GetDebtAmountDollar2: 3.8707e+006  
  11. BillNo: 3870736 BillName: OrderBill.  
  12. cast fail:  

参考: 《C++ Primer 3rd Edition》
posted @ 2017-05-11 09:33  鱼酱  阅读(190)  评论(0编辑  收藏  举报

https://img-blog.csdnimg.cn/32db9ce43ef64316a2e37a31f4cee033.gif
编程小鱼酱yu612.com,点击前往