[C/C++]_[使用dynamic_cast 强制转换的优点]
时间:2014-05-03 21:55:11
收藏:0
阅读:333
场景:
1. C++引入了dynamic_cast 这种类型识别的强制转换,对识别错误的程序是有好处的,建议能用的地方就用,它能在转换错误时返回0或抛出异常,比起C的旧强制转换
执行转换了不对类型依旧不会报错可靠些,因为这类错误如果发生了,其实很难找出来。
好处:
1.用在多态的子类情况下,父类不能提供处理接口,这时可以针对子类做特殊的处理。
2.dynamic_cast比另外3个cast优势就是会对转换进行检查,如果出错,会报错。
补充一个知识点: 左值和右值 (摘录自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:
评论(0)