关闭

boost之路 十六 类型转换操作符

283人阅读 评论(0) 收藏 举报
分类:


Boost.Conversion 库由两个文件组成。分别在 boost/cast.hpp 文件中定义了 boost::polymorphic_castboost::polymorphic_downcast 这两个类型转换操作符, 在 boost/lexical_cast.hpp 文件中定义了 boost::lexical_cast

boost::polymorphic_castboost::polymorphic_downcast 是为了使原来用 dynamic_cast 实现的类型转换更加具体。具体细节,如下例所示。

struct father 
{ 
  virtual ~father() { }; 
}; 

struct mother 
{ 
  virtual ~mother() { }; 
}; 

struct child : 
  public father, 
  public mother 
{ 
}; 

void func(father *f) 
{ 
  child *c = dynamic_cast<child*>(f); 
} 

int main() 
{ 
  child *c = new child; 
  func(c); 

  father *f = new child; 
  mother *m = dynamic_cast<mother*>(f); 
} 

本例使用 dynamic_cast 类型转换操作符两次: 在 func() 函数中,它将指向父类的指针转换为指向子类的指针。在 main() 中, 它将一个指向父类的指针转为指向另一个父类的指针。第一个转换称为向下转换(downcast),第二个转换称为交叉转换(cross cast)。

通过使用 Boost.Conversion 的类型转换操作符,可以将向下转换和交叉转换区分开来。

#include <boost/cast.hpp> 

struct father 
{ 
  virtual ~father() { }; 
}; 

struct mother 
{ 
  virtual ~mother() { }; 
}; 

struct child : 
  public father, 
  public mother 
{ 
}; 

void func(father *f) 
{ 
  child *c = boost::polymorphic_downcast<child*>(f); 
} 

int main() 
{ 
  child *c = new child; 
  func(c); 

  father *f = new child; 
  mother *m = boost::polymorphic_cast<mother*>(f); 
} 

boost::polymorphic_downcast 类型转换操作符只能用于向下转换。 它内部使用 static_cast 实现类型转换。 由于 static_cast 并不动态检查类型转换是否合法,所以 boost::polymorphic_downcast 应该只在类型转换是安全的情况下使用。 在调试(debug builds)模式下, boost::polymorphic_downcast 实际上在 assert ()函数中使用 dynamic_cast 验证类型转换是否合法。 请注意这种合法性检测只在定义了NDEBUG宏的情况下执行,这通常是在调试模式下。

向下转换最好使用 boost::polymorphic_downcast, 那么 boost::polymorphic_cast 就是交叉转换所需要的了。 由于 dynamic_cast 是唯一能实现交叉转换的类型转换操作符,boost::polymorphic_cast 内部使用了它。 由于 boost::polymorphic_cast 能够在错误的时候抛出 std::bad_cast 类型的异常,所以优先使用这个类型转换操作符还是很有必要的。相反,dynamic_cast 在类型转换失败使将返回0。 避免手工验证返回值,boost::polymorphic_cast 提供了自动化的替代方式。

boost::polymorphic_downcastboost::polymorphic_cast 只在指针必须转换的时候使用;否则,必须使用 dynamic_cast 执行转换。 由于 boost::polymorphic_downcast 是基于 static_cast,所以它不能够,比如说,将父类对象转换为子类对象。 如果转换的类型不是指针,则使用 boost::polymorphic_cast 执行类型转换也没有什么意义,而在这种情况下使用 dynamic_cast 还会抛出一个 std::bad_cast 异常。

虽然所有的类型转换都可用 dynamic_cast 实现,可 boost::polymorphic_downcastboost::polymorphic_cast 也不是真正随意使用的。 Boost.Conversion 还提供了另外一种在实践中很有用的类型转换操作符。 体会一下下面的例子。

#include <boost/lexical_cast.hpp> 
#include <string> 
#include <iostream> 

int main() 
{ 
  std::string s = boost::lexical_cast<std::string>(169); 
  std::cout << s << std::endl; 
  double d = boost::lexical_cast<double>(s); 
  std::cout << d << std::endl; 
} 

类型转换操作符 boost::lexical_cast 可将数字转换为其他类型。 例子首先将整数169转换为字符串,然后将字符串转换为浮点数。

boost::lexical_cast 内部使用流(streams)执行转换操作。 因此,只有那些重载了 operator<<()operator>>() 这两个操作符的类型可以转换。 使用 boost::lexical_cast 的优点是类型转换出现在一行代码之内,无需手工操作流(streams)。 由于流的用法对于类型转换不能立刻理解代码含义, 而 boost::lexical_cast 类型转换操作符还可以使代码更有意义,更加容易理解。

请注意 boost::lexical_cast 并不总是访问流(streams);它自己也优化了一些数据类型的转换。

如果转换失败,则抛出 boost::bad_lexical_cast 类型的异常,它继承自 std::bad_cast

#include <boost/lexical_cast.hpp> 
#include <string> 
#include <iostream> 

int main() 
{ 
  try 
  { 
    int i = boost::lexical_cast<int>("abc"); 
    std::cout << i << std::endl; 
  } 
  catch (boost::bad_lexical_cast &e) 
  { 
    std::cerr << e.what() << std::endl; 
  } 
} 

本例由于字符串 "abc" 不能转换为 int 类型的数字而抛出异常。


16.3. Boost.NumericConversion

Boost.NumericConversion 可将一种数值类型转换为不同的数值类型。 在C++里, 这种转换可以隐式地发生,如下面例所示。

#include <iostream> 

int main() 
{ 
  int i = 0x10000; 
  short s = i; 
  std::cout << s << std::endl; 
} 

由于从 intshort 的类型转换自动产生,所以本例编译没有错误。 虽然本例可以运行,但结果由于依赖具体的编译器实现而结果无法预期。 数字0x10000对于变量 i 来说太大而不能存储在 short 类型的变量中。 依据C++标准,这个操作的结果是实现定义的("implementation defined")。 用Visual C++ 2008编译,应用程序显示的是0s 的值当然不同于 i 的值。

为避免这种数值转换错误,可以使用 boost::numeric_cast 类型转换操作符。

#include <boost/numeric/conversion/cast.hpp> 
#include <iostream> 

int main() 
{ 
  try 
  { 
    int i = 0x10000; 
    short s = boost::numeric_cast<short>(i); 
    std::cout << s << std::endl; 
  } 
  catch (boost::numeric::bad_numeric_cast &e) 
  { 
    std::cerr << e.what() << std::endl; 
  } 
} 

boost::numeric_cast 的用法与C++类型转换操作符非常相似。 当然需要包含正确的头文件;就是 boost/numeric/conversion/cast.hpp

boost::numeric_cast 执行与C++相同的隐式转换操作。 但是,boost::numeric_cast 验证了在不改变数值的情况下转换是否能够发生。 前面给的应用例子,转换不能发生,因而由于0x10000太大而不能存储在 short 类型的变量上,而抛出 boost::numeric::bad_numeric_cast 异常。

严格来讲,抛出的是 boost::numeric::positive_overflow 类型的异常,这个类型特指所谓的溢出(overflow) - 在此例中是正数。 相应地,还存在着 boost::numeric::negative_overflow 类型的异常,它特指负数的溢出。

#include <boost/numeric/conversion/cast.hpp> 
#include <iostream> 

int main() 
{ 
  try 
  { 
    int i = -0x10000; 
    short s = boost::numeric_cast<short>(i); 
    std::cout << s << std::endl; 
  } 
  catch (boost::numeric::negative_overflow &e) 
  { 
    std::cerr << e.what() << std::endl; 
  } 
} 

Boost.NumericConversion 还定义了其他的异常类型,都继承自 boost::numeric::bad_numeric_cast。 因为 boost::numeric::bad_numeric_cast 继承自 std::bad_cast,所以 catch 处理也可以捕获这个类型的异常。

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Boost的转换函数polymorphic_cast和polymorphic_downcast

Boost的转换函数(一) Boost的转换函数是对C++中的四种类型转换函数(const_cast,reinterpret_cast,static_cast,dynamic_cast)的一...
  • freeboy1015
  • freeboy1015
  • 2012-07-26 10:35
  • 655

C++学习 boost学习之-polymorphic_downcast

Boost中文手册下载:http://download.csdn.net/detail/skdkjxy/8723045 用法: 1 polymorphic_downcast在调试状态下会测试转换是否成...
  • skdkjxy
  • skdkjxy
  • 2015-05-27 14:22
  • 504

Boost 学习之算法篇 hex

原文链接:http://www.boost.org/doc/libs/1_60_0/libs/algorithm/doc/html/the_boost_algorithm_library/Misc/h...
  • baijiaheizhiganmao
  • baijiaheizhiganmao
  • 2016-02-29 13:25
  • 1234

C/C++ —— 十六进制类型字符串的转换

在实际工作中,字符串和其它数据类型的转换是很常见的,库函数有很多,比如 atoi , strtol , sscanf 等,这些函数网上有很多资料, 我经常用到的就是十六进制的数值以字符串的形式传输,...
  • jscese
  • jscese
  • 2014-09-04 18:57
  • 4333

Hex与Double类型之间的转换

unsigned int getbitu(const unsigned char *buff, int pos, int len) {unsigned int bits=0; int i; for ...
  • u011859369
  • u011859369
  • 2015-12-02 16:48
  • 2441

java学习之路 之 高级类特性1-instanceof操作符、对象类型转换(造型)

instanceof 操作符 x instanceof A:检验x是否为类A的对象,返回值为boolean型。 要求x所属的类与类A必须是子类和父类的关系,否则编译错误。 如果x属于类A的子类B,x ...
  • OnlyLove_longshao
  • OnlyLove_longshao
  • 2016-08-07 21:37
  • 1033

boost 类型转换操作符

目录 16.1 概述16.2 Boost.Conversion16.3 Boost.NumericConversion  该书采用 Creative Commons License...
  • llambkin
  • llambkin
  • 2013-05-04 18:42
  • 512

boost 类型转换操作符

struct father { virtual ~father() { }; }; struct mother { virtual ~mother() { }; }; stru...
  • mengzhisuoliu
  • mengzhisuoliu
  • 2017-11-24 14:19
  • 57

菜鸟的 PHP 学习之路(四):PHP 的数据类型转换

虽然 PHP 是一门弱类型的语言,但个人觉得类型还是有必要存在的,有时我们就会需要对变量进行类型转换。 在 PHP 中有两种方式让你进行类型转换:强制类型转换和 settype() 函数类型转换。 ...
  • shawearn1027
  • shawearn1027
  • 2015-01-05 12:58
  • 353

C#学习之路,学习笔记 第三章 运算符和表达式(运算符、优先级、类型转换)

C#学习之路,学习笔记 第三章 运算符和表达式(运算符、优先级、类型转换)
  • gaohua106
  • gaohua106
  • 2015-10-06 19:08
  • 245
    个人资料
    • 访问:127082次
    • 积分:3666
    • 等级:
    • 排名:第10307名
    • 原创:300篇
    • 转载:47篇
    • 译文:0篇
    • 评论:17条
    文章分类
    最新评论