广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++中Boost的转换函数
  • 564
分享到

C++中Boost的转换函数

2024-04-02 19:04:59 564人浏览 独家记忆
摘要

Boost的转换函数是对c++中的四种类型转换函数(const_cast,reinterpret_cast,static_cast,dynamic_cast)的一些补充和扩展,在阅读

Boost的转换函数是对c++中的四种类型转换函数(const_cast,reinterpret_cast,static_cast,dynamic_cast)的一些补充和扩展,在阅读本文前,请先熟悉C++中的四种类型转换函数相关知识。

polymorphic_cast

C++提供了dynamic_cast来实现运行时的类型转换,但是如果用来转换指针时,需要记得检查返回值(这是很多程序员容易忘掉的地方),否则一旦转换失败,将获得一个NULL指针,无异于给程序埋下了一个定时炸弹。

Boost的polymorphic_cast在dynamic_cast的基础上增加了对返回值的检测,如果转换失败,它就会抛出std::bad_cast异常。其函数体如下:

template <class Target, class Source>
inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
{
    Target tmp = dynamic_cast<Target>(x);
    if ( tmp == 0 ) throw std::bad_cast();
    return tmp;
}

虽然抛异常增加了开销,但使用起来却更加简单了。

polymorphic_downcast

由于抛出异常会降低程序的效率,而且dynamic_cast更会查询一个type_info结构来确定正确的类型,所以不管是空间上的成本还是时间上的成本,都会大大增加。在一些应用场景中,只需要在编译期间进行类型转换即可。这时我们可以使用static_cast来实现编译期间的类型转换,但static_cast可能导致错误的类型转换:

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

class B:public A{};
class C:public A{};

int main()
{
    A *pa = new C();
    B *pb = static_cast<B*>(pa);
}

对于上述程序,虽然pa和pb间没有继承关系,但是这个转换却可以通过,运行时也不会报任何错误,可一旦对pb进行访问,就会得到错误的结果甚至直接导致程序死掉。

polymorphic_downcast就巧妙的解决的这一问题,首先还是先看看它的定义:

template <class Target, class Source>
inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
{
    BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
    return static_cast<Target>(x);
}

从它的定义可以看出,在运行Release模式下,它和是static_cast一样的,也就是说它的Release版具有和static_cast一样的开销。但在Debug模式下,它会首先进行一次动态转换,而一旦类型不匹配,就会抛出异常。

在上述程序中,如果用polymorphic_downcast来替换static_cast的话,我们可以先在Debug模式下运行程序,如果有错误的类型转换,将很容易的检测出来。待改正所有的错误后,再发布Release版,这样即没有动态转换造成的开销,又杜绝了错误的类型转换。

boost::numeric_cast

在c++中,我们经常需要把不同类型的数字互相转换,如将一个数字在long和short之间转换。但由于各数字的精度不同,当一个数字从"大"类型到"小"类型就可能导致转换失败,如下所示:

long n1 = 99999999;
short n2 = static_cast<short>(n1);

对于如上转换,n2得到的是一个负数,显然这个不是我们所期望的,并且这种运行时的错误是很难检测的,一旦使用了这个错误的转换后的数据,后果不堪设想。

boost::numeric_cast可以帮助我们解决这一问题,对于上面的转换,boost::numeric_cast会抛出一个boost:: bad_numeric_cast这个异常对象。从而保证转换后值的有效性。上述代码可以改写为如下:

try
{
    long n1 = 99999999;
    short n2 = boost::numeric_cast<short>(n1);
}
catch(boost::bad_numeric_cast&)
{
    std::cout<<"The conversion failed"<<std::endl;
}

numeric_cast是如何知道这样的数字转换失败的呢?numeric_cast合理的应用了std::numeric_limits<>,而std::numeric_limits<>就是内建数字类型的type_tratis。当然也可以将自己定义的数字抽象类型添加到std::numeric_limits<>的特化版本中,这样numeric_cast就可以作用于自定义的类型了。由于相对复杂点,本文是介绍其功能和用法,就不分析其源码了,感兴趣的朋友可以参看boost文档和代码。

对于numeric_cast的使用也是有些要求的。

  • 源类型和目标类型必须都是可拷贝构造的

  • 源类型和目标类型必须都是数字型类型。也就是被std::numeric_limits<>::is_specialized的特化定义为true

  • 源类型必须能被static_cast转换为目标类型

其实对我们用的系统内置的数字来说,这几条都不是限制,只有我们在需要通过它转换自定义的数据类型时,才需要注意,否则编译不通过(其实这个错误还比较好发现和解决)。

boost::lexical_cast

C/C++程序开发中,往往需要将数字型对象的值转换为字符文本格式,或反之操作。虽然C语言就提供了不少系统函数来进行这种操作,如scanf、atoi等。这些函数小巧简洁,使用很方便,但缺少扩展性。在std中引入了stringstream来以一个通用的方式实现各种转换,但缺少对错误转换的检测。而boost::lexical_cast是在stringstream上的一个扩展,增加了对错误的类型转换的检测:

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

using namespace std;

int main()
{     
    try
    {
        int i = 100;
        string str = boost::lexical_cast<string>(i);
        cout<<"The string is:"<<str<<endl;
        str = "error";
        i = boost::lexical_cast<int>(str);
    }
    catch(boost::bad_lexical_cast& exobj)
    {
        cout<<"Convert err:"<<endl;
        cout<<exobj.what()<<endl;
    }
}

在上述转换中,第二个转换从"err"到int的转换是失败的,会抛出一个boost::bad_lexical_cast的异常,从而能帮助我们构造更安全稳定的程序。

boost::lexical_cast内部实现其实也是一个stringstream的封装,其函数简化如下:

template<typename Target,typename Source>
Target lexical_cast(Source arg){
    detail::lexical_stream<Target,Source> interpreter;
    Target result;
    if(!(interpreter<<arg && interpreter>>result))
        throw_exception(bad_lexical_cast(typeid(Target),typeid(Source)));
    return result;
}

其中lexical_stream<>对字符串流做了一系列的包装,主要提供了operator<<(Source)和operator>>(Target)操作,用于判断操作是否成功。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: C++中Boost的转换函数

本文链接: https://www.lsjlt.com/news/151670.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++中Boost的转换函数
    Boost的转换函数是对C++中的四种类型转换函数(const_cast,reinterpret_cast,static_cast,dynamic_cast)的一些补充和扩展,在阅读...
    99+
    2022-11-13
  • C++使用boost::lexical_cast进行数值转换
    在STL库中,我们可以通过stringstream来实现字符串和数字间的转换: int i = 0; stringstream ss; ss <<...
    99+
    2022-11-13
  • C++中类的转换函数怎么用
    今天小编给大家分享一下C++中类的转换函数怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。只有接受一个参数(其他参数有默...
    99+
    2023-06-29
  • C++中类的转换函数你了解吗
    只有接受一个参数(其他参数有默认值的也算)的构造函数才能作为转换构造函数。 在C++中,接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了蓝图。因此,下面的构造函数用于将d...
    99+
    2022-11-13
  • C++中怎么强制类型转换函数
    本篇文章给大家分享的是有关C++中怎么强制类型转换函数,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1)static_cast<T*>(a)将地址a转换成类型T,T...
    99+
    2023-06-17
  • C#中怎么自定义类型转换函数
    C#中怎么自定义类型转换函数,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。/// <summary>  /// 将字符型...
    99+
    2023-06-18
  • C++ 转换函数用法案例详解
    1.标准数据之间会进行隐式类型安全转换,规则如下:  在这里主要探讨c++中类类型与普通类型的转换: 1.类类型转换普通类型 class Fraction { pub...
    99+
    2022-11-12
  • C++中转换构造函数与默认函数的优先级是什么
    今天小编给大家分享一下C++中转换构造函数与默认函数的优先级是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面...
    99+
    2022-10-19
  • C++ 如何将Lambda转换成函数指针
    目录参考下面的代码下面是类型转换运算符实现的一行关键汇编代码没有捕获任何变量的Lambda表达式可以转换成与它的调用原型一致的函数指针。 参考下面的代码 void example1(...
    99+
    2022-11-13
    C++ Lambda C++函数指针 Lambda转成函数指针
  • C++11的string的数值转换函数方法是什么
    这篇文章主要介绍“C++11的string的数值转换函数方法是什么”,在日常操作中,相信很多人在C++11的string的数值转换函数方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++11的str...
    99+
    2023-06-19
  • C语言的字符串转换函数怎么用
    这篇“C语言的字符串转换函数怎么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言的字符串转换函数怎么用”文章吧。字符串...
    99+
    2023-06-29
  • C++中的boost::function库简介
    boost::function Boost.Function库用来提供一个对象化的函数指针,通过它可以很容易的将一个函数封装为仿函数。 boost::function库可以支持自由函...
    99+
    2022-11-13
  • C++中Operator类型强制转换成员函数解析
    类型转换操作符(type conversion operator)是一种特殊的类成员函数,它定义将类类型值转变为其他类型值的转换。转换操作符在类定义体内声明,在保留字 operato...
    99+
    2022-11-15
    类型强制转换 Operator C++
  • C++图文并茂讲解类型转换函数
    目录一、类型转换函数(上)1.再论类型转换2.问题3.再论构造函数4.另一个视角5.编译器的行为6.小结(上) 二、类型转换函数(下)1.类型转换2.编译器的行为3.注意事...
    99+
    2022-11-13
  • C++中Boost的智能指针scoped_ptr
    boost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示了该指针的基本应用: #includ...
    99+
    2022-11-13
  • C++中Boost的智能指针shared_ptr
    boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限。顾名思义,boost::shar...
    99+
    2022-11-13
  • C++中Boost的智能指针weak_ptr
    循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象。一个简单的例子如下: #include <string> #includ...
    99+
    2022-11-13
  • Oracle中转换函数有哪些
    这篇文章主要为大家展示了“Oracle中转换函数有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Oracle中转换函数有哪些”这篇文章吧。转换函数   &nbs...
    99+
    2023-06-03
  • VBS中有哪些转换函数
    本篇文章为大家展示了怎么在VBS中有哪些转换函数,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。转换函数Asc 函数CBool 函数CByte 函数CCur 函数CDate 函数CDbl 函数Chr ...
    99+
    2023-06-08
  • C#中数据类型的转换介绍
    目录1、parse转换:将string类型转化为其他类型2、任意类型转化为string类型3、隐式转换:自动转换-->小范围到大范围自动转换4、显示转换:强制转换-->由...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作