shellmad-06_C++新特性 强制转换const_cast

类型转换
以下程序编译不通过, 因为相当于将整形n当成地址赋给指针

#include <iostream>
using namespace std;
int main(){
    int n = 1;

    int *p = n;
    return 0;
}

但是C语言类型可以强转, 可以编译通过, 也可以正常运行

#include <iostream>
using namespace std;
int main(){
    int n = 1;

    int *p = (int*)n;
    return 0;
}

因为我们并没有真正使用p的值, 除非你这样做

可以编译通过, 但是运行的时候会出错, Segmentation fault: 11, 因为在地址为0x1的地方, 赋值, 这是不允许的
很显然, 这是强转所带来的隐患

#include <iostream>
using namespace std;
int main(){
    int n = 1;

    int *p = (int*)n;

    *p = 1;
    return 0;
}

不仅如此, 当前是把整数转换为一个指针, 基类->派生类, 因为派生类的成员可能更多, 指针就会访问到不该访问的地方, 就会出错

函数指针->函数指针, 两个函数参数可能不一样

针对这样的情况, C++推出了4种功能不同的强制类型转换运算符
使用C++提供的4种强制类型转换运算符, 可以在编译器的角度上最大的去支持检测, 通过编译器去检测安全性, 从而让代码更加的健壮

  • const cast(用的比较多
  • static cast(用的比较多
  • reinterpret_cast(用的很少, 基本跟C语言差不多)
  • dynamic_cast(虚元素)

const_cast

仅用于进行去除 const 属性的转换,它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。

接下来看下const_cast怎么用的, 以及在什么样的场合使用

const_cast (parameter)
<>号填要强制转换的类型, ()内填要强制转换的变量

程序分析:

...

int main(){
	const int n = 5;
	// const_cast 只针对指针, 引用, this指针
	int k = const_cast<int> (n)
}

运行后会报错:
“const_cast” : 无法从“const int " 转换为"int"
const_cast中的类型必须是指针, 引用或指向对象类型成员的指针
在这里插入图片描述

报错的意思是, ()内只能填写地址, <>内只能填写指针类型
因此不能把const int类型转换成int, 这是不对的,

#include <iostream>
using namespace std;
int main(){
    const int n = 5;
	//const_cast 只针对指针, 引用, this指针
    int *k = const_cast<int*> (&n);
    int &kRef = const_cast<int&> (n);
    return 0;
}

在这里插入图片描述
在这里插入图片描述
n的值原先为const int, 值是不能改变的,通过const_cast, 去除const属性后, 可以改变, 引用也是同样的道理

this指针

类里面有一种成员函数, 叫做常成员函数, 常成员函数不能修改成员变量的值
改一下的话, 会报错
在这里插入图片描述
不能改的原因, 是因为这里的this指针的类型是特殊的, 是const CTest *const类型
在这里插入图片描述
前面这个const, 相当于const int *p, 代表指针指向的内容不能更改

报错示意图:在这里插入图片描述

反过来 int * const p, 表示p本身, 即指针的地址不能改变, 即 指针的指向不能变

报错示意图:
在这里插入图片描述

回到this指针, 因为this指针前面多了const, 常成员函数中, 不能修改成员变量的值. 因为常成员函数const, 会对this指针前面添加const修饰, 所以不能改

所以可以利用const_cast来去掉前面的const属性

class CTest{
public:
    void foo(int nTest) const{
        const_cast<CTest *const>(this)->m_test = nTest; // 注意<>中的类型为CTest const*, 表示指向不能更改
    }
private:
    int m_test;
};

总代码:

#include <iostream>
using namespace std;

class CTest{
public:
    void foo(int nTest) const{
        const_cast<CTest *const>(this)->m_test = nTest;
    }
private:
    int m_test;
};
int main(){
    const int n = 5;
    
    //const_cast 只针对指针, 引用, this指针
    int *k = const_cast<int*> (&n);
    // *k = 123;
    int &kRef = const_cast<int&> (n);
    // kRef = 456;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值