C++-C++中的类型转换

发布于 2016-10-25 13:14:42 字数 88 浏览 1140 评论 4

static_cast、dynamic_cast、const_static、reinterpret_cast有什么区别,怎么使用?(很多书中都讲的很粗略,不到位)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泛泛之交 2017-07-21 16:42:49

(1)static_cast: 一般的转换,它是静态的检测,无法运行时检测类型,在继承中尤为突出。
适用范围:

A、用于所有系统类型之间转化,不能用于系统类型指针类型转化
用于继承类之间的转化(含指针),不能用于其他没有隐式转化的对象类型之间的转化
实例:

double t_d = 0;
int t_i= static_cast<int>(t_d); //是合法的转化
//而企图将double*->int*是不允许的

B、用于继承类之间的转化(含指针),不能用于其他没有隐式转化的对象类型之间的转化
继承的例子:

class x
{
};
class y: public x
{
};
x t_o_x;
y t_o_y = static_cast<y>(t_o_x); //x* y*转化也可以进行因为x,y继承关系,类型可以自动隐式转化使用

隐式转换的例子:

 class x
{
};
class y
{

public:
y( x i_x ) {}
};
x t_o_x;
y t_o_y = static_cast<y>(t_o_x); //大家看到y构造函数可以对于x类型隐式转化
//所以可以将x->y,如果企图将y->x会报错

(2)reinterpret_cast: 主要用于对于指针类型的强制转化,some_type* -> special_type*这样转化,类型信息可以是不完全的。它允许将任意指针转化到其他类型指针,也允许任意整数类型到任意指针类型转化(BT)。这样导致的结果是极其不安全的,不能安全的应用于其他目的,除非转化到原来类型。

例子:

 <1> 使用所有整形可以转化为任意类型的指针(指针是4字节的long的东东,那么机器就认为同类型就是可以转化)
int c;
x* p = reinterpret_cast<x*>(c); //x是自定义的任意类型,当然包括系统类型
<2> 可以对于任意类型指针之间转化
y* c;
x* p = reinterpret_cast<x*>(c);//x,y代表所有自定义或系统类型

(3)const_cast: 主要针对const和volatile的转换.
仅仅为了去掉或着加上const修饰符号。但是对于本身定义时为const的类型,即使你去掉const性,在你操作这片内容时候也要小心,只能r不能w操作,否则还是会出错。

 const char* p = "123";
char* c = const_cast<char*>(p);
c[0] = 1; //表面上通过编译去掉了const性,但是操作其地址时系统依然不允许这么做。这是一个漏洞吧

(4)dynamic_cast: 通常在基类和派生类之间转换时使用,run-time cast
例子:

 class B {}; //polymorphic类型含virtual才能dynamic_cast
class D: public B {}
void f( B* pb )
{
D* pd1 = dynamic_cast<D*>(pb);//如果pb为d类型正确返回,如果不是返回0
D* pd2 = static_cast<D*>(pb); //不管怎么样都返回指针有可能指向不合适的对
//象,因为static仅仅静态检测,不能得到运
//行时对象的信息是否真正为D类型
}

在继承方面dynamic_cast和reinterpret_cast又有着很大差别,具体可以参考:
转换符dynamic_cast和reinterpret_cast

泛泛之交 2017-06-01 20:02:18

1.static_cast 最常用的类型转换符,在正常状况下的类型转换。

2.const_cast 用于取出const属性,把const类型的指针变为非const类型的指针。

3.dynamic_cast 该操作符用于运行时检查该转换是否类型安全,但只在多态类型时合法,即该类至少具有一个虚拟方法。通常在基类和派生类之间转换时使用。

4.reinterpret_cast 用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整形数。

浮生未歇 2017-01-30 11:44:33

const_cast转换符是用来移除变量的const或volatile限定符。
详细请看:C++标准转换运算符const_cast
static_cast转换符用来对两种有一定关系的类型进行转换。
详细请看:C++标准转换运算符static_cast
dynamic_cast是用来检查两者是否有继承关系。
详细请看:C++标准转换运算符dynamic_cast
reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。
详细请看:C++标准转换运算符reinterpret_cast

归属感 2016-11-24 16:48:22

自己用通俗的语言跟你讲一遍吧:

static_cast:干杂活的,那三个都有各自的专有用途,那三个不做的都由这个转型符来做,只要它能做的,用C语法的强制类型转换运算符也一定能够完成;但话又说回来了,C强制类型转换能做的,它可不一定都能做,比如去除const性。
此外在这里声明一点,一般人都不会清楚都不会注意到的一点,就是四个之中只有它可以用于非指针非引用类型的转换,其他三个运算符基本上都是专门和指针或者引用打交道的。

const_static:去除“指针”或“引用”的const、volatile、__unaligned性。很多人都以为用这个运算符就可以让const这么“固若金汤”的东西“形同虚设”,实则不然,本质上它能做的也就仅仅是为你剥去一层虚假的外壳,如果“被指向”或“被引用”的东西本身就是const的,那任凭你费多大力气都是徒劳的。一般它都是用在这样的一套逻辑中:
int a=34;const int * pcint=&a;int pint=const_cast<int>(pcint);pint=0;这样就修改了本来是const的指针《该指针要求不能修改它指向的东东》,这里如果改为const int a=34;那么虽然编译依然能通过,运行依然OK,但是实际上当你用pint来修改时,你会得到修改后的值为:a依然为34;而*pint确实为0了,但有趣的是此时pint=&a依然成立,虽然pint指向a,但是取出它的值却不等于a了。至此,希望大家今后不要再误用const_cast了。

dynamic_cast:用精炼的语言概括,就是专门用于面向对象中的down cast的。但是有三点是前提:第一,必须用于类和子类之间的转换;第二,必须用于指针或引用类型的转换;第三,基类必须有虚函数。

reinterpret_cast:用于对指针的重新包装,也就是指针类别之间的转化,除此之外,还可以用于指针类型和unsigned int类型之间的转化。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文