4.6 使用第三方库
以上介绍了Visual C++对对象赋值、转换及字符编码转换的方法,实际上还有一些好用的第三方类库用以辅助C++程序员完成对象处理,比较著名的就是boost。本节简单介 绍boost库中与数值相关的boost::any、boost::lexical_cast,以及有理数类boost::rational。
4.6.1 万能类型boost::any
boost库提供了any类,boost::any是一个能保存任意类型值的类,这一点有点像variant类型,不过variant由于采用了一 个巨大的union,效率非常低。而boost利用模板,保存的时候并不改变值的类型,只是在需要的时候才提供方法让用户进行类型判断及取值。
boost::any几乎可以用来存储任何数据类型:
boost::any ai, as; ai = 100; as = string( "hello" );
需要的时候,我们又可以使用any_cast将原来的数据还原:
int i = boost::any_cast< int >(ai); string s = boost::any_cast<string>(as);
当这种转换发生类型不匹配时,会有异常bad_any_cast发生:
try { int i = boost::any_cast< int >(as); } catch (boost::bad_any_cast & e) { }
在传统的C++程序中,为了支持各种数据类型,我们不得不使用万能指针"void *",但是很遗憾的是,基于万能指针的转换是不安全的,"void*"缺少类型检查。所以,我们建议大家尽量使用any类。
现在动手
编写如下程序,体验如何使用boost::any来完成对象类型转换。
【程序 4-10】使用boost::any完成对象类型转换
#include "stdafx.h" #include "boost/any.hpp" #include <string> using namespace std; using namespace boost; class Cat { }; void print(any it) { if(it.empty()) { printf("nothing!/r/n"); return; } if(it.type() == typeid(int)) { printf("integer: %d/r/n", any_cast<int>(it)); return; } if(it.type() == typeid(string)) { printf("string: %s/r/n", any_cast<string>(it).c_str()); return; } if(it.type() == typeid(CString)) { _tprintf(_T("CString: %s/r/n"), any_cast<CString>(it)); return; } if(it.type() == typeid(Cat)) { _tprintf(_T("oops! a cat!/r/n")); return; } } int main() { print(100); any as[] = {any(), 100, string("hello"), CString("world"), Cat()}; for(int i = 0; i < sizeof(as) / sizeof(as[0]); i++) { print(as[i]); } return 0; }
结果输出如图4-18所示。
(点击查看大图)图4-18 运行结果 |
光盘导读
该项目对应于光盘中的目录"/ch04/BoostAnyTest"。