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 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[i];
- 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》