CPP {类型强转,reinterpret_cast,static_cast}

CPP {类型强转,reinterpret_cast,static_cast}

@LOC_1

@LOC: 2

static_cast

性质

ST * s = new ST 此时static_cast<ST*>(s) != nullptr, 而如果你s = nullptr后 会发现static_cast<ST*>(s) == nullptr 这说明 他看的 不是ST *这个静态类型 而是看他的值;

@DELI;

static_cast<T>(a)(T)a方式, 并不是等价的; (比如@LINK: @LOC_0);

reinterpret_cast

定义

#用途1#
指针的强转, 从void*转换成T*;
.T*转换为void* 这是可以隐式强转的, 但反过来 给你一个void*(但前提是你知道 他本质上是T*), 他不可以直接强转到T*, 那么此时 这就可以T* = reinterpret_cast<T*>(void*);

#用途2#
指针的地址 转换为 整数类型;
. 我们知道 指针可以输出(16进制的地址), 但如果我们想得到其地址对应的整数呢? 此时static_cast<int64>(&p)是不可以的 (但(int64)&p是可以的…), 但还可以使用reinterpret_cast<int64>( &p); (@MARK: @LOC_0);

类型强转

性质

@LINK: https://editor.csdn.net/md/?articleId=126769957-(@LOC_0);
T, unsigned T混合时 会自动转为unsigned T;

@DELI;

(Mod)-1, 她会调用Mod(int)这个构造函数; 即她和Mod(-1)的效果是一样的;
(int)Mod(), 她会调用Mod.int()这个类型强转运算符;
int( Mod()), 这是错误语法, 因为int并没有一个接受Mod的构造函数;

错误

@DELI;

有符号整型的负数 进行强转, 他很智能… 会保持值不变, 而不是直接的比特位复制;
int8 a = -1, 执行int32 b = a; 你是否会认为, b的低8位就是a 然后高位都是0, 即00 00 00 FF, 这是错误的; 他的强转 是要保证值不变的, 即原来a==-1, 现在一定也b==-1, 即b = F...F;
. 只有涉及到有符号数的负数时 会这样, 其他情况的话 比如当a >= 0时, 此时确实是: b的低8位就是a 然后高位都是0, 这很符合直觉…

@DELI;

MARK: @LOC_1;

class A{
	A( double a); // double可以*隐式*强转给A
	operator double() const; // A可以*隐式*强转给double
	
	A operator*( A _a){ ...}
};

A a; (int/double) b;
1: 对于b * a, 他等价于: b * (double)a, a被隐式强转为了double, 他不会使用A的乘法规则; (比如2*a, 2.0*a 都是使用的double的乘法规则 不是A的);
2: 对于a * b, 此时有产生歧义! 有2个乘法规则都可以使用 因此冲突了, 一个是(double)a * b (即A被隐式强转为了double 他使用的是double的乘法), 令一个是a * (A)b (即b隐式强转为了A类型 他使用的是A的乘法);

此时 错误还是挺多的:
+: 上面的1:, 我们想让他调用我们自己的A的乘法规则 但是他却把A给隐式强转给了double; 解决办法是: 取消A的隐式强转;
+: 上面的2:, 我们选择这2个歧义版本中的 A的乘法这个;
综上 解决办法是: 将强转运算符重载 改为显式, 即explicit operator double() ..., 这样对于a*b/ b*a 他只会对应A的乘法规则;

应用

@DELI;

#类型运算符重载#
MARK: @LOC_0;

class A{
	[explicit] operator double() const{ return 3.33;}
};

A a;, 此时A可以强转为double, 即(double)a, double(a)这2种方式 都会调用上面这个运算符函数

规范: 强转运算符重载 必须要带explicit显式; (参见: LINK: @LOC_1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值