概述
C语言中经常会遇到类型的强转,强制类型转换是有一定风险的,有的转换并不一定安全,如把整型数值转换成指针,把基类指针转换成派生类指针,把一种函数指针转换成另一种函数指针,把常量指针转换成非常量指针等。
这里写目录标题
- 1.C语言中强转的方法及问题
- 1.1 C语言中的强转方法
- 1.2 C语言强制类型转换缺点
- 2. 强制转换运算符
- 3.const_cast
- 3.1 常用方法:利用const_cast 转换为同类型的非 const 引用或者指针
- 3.2 常成员函数中去除this指针的const属性
- 3.2.1 常成员函数不能修改成员变量的值
- 3.2.2 为什么常成员函数不能修改成员变量的原因
- 3.2.3 可以通过const_cast去除类前面的const属性
1.C语言中强转的方法及问题
1.1 C语言中的强转方法
int n = 1;
//将n的地址赋给指针p
//int* p = &n;
//c语言中进行强制转换,将n作为一个地址赋给p
//p是带有类型的地址
int* p = (int*)n;
当对地址为1的p进行访问的时候,会报如下错误:
int main()
{
int n = 1;
//c语言中进行强制转换,将n作为一个地址赋给p
//p是带有类型的地址
int* p = (int*)n;
//代表在地址为1的地方赋值为1
*p = 1;
return 0;
}
基类转换为派生类的问题:由于派生类可能成员更多,基类转换为派生类可能越界访问。
函数指针的问题:由于函数的参数存在差异
1.2 C语言强制类型转换缺点
主要是为了克服C语言强制类型转换的以下三个缺点。
-
没有从形式上体现转换功能和风险的不同。
例如,将 int 强制转换成 double 是没有风险的,而将常量指针转换成非常量指针,将基类指针转换成派生类指针都是高风险的,而且后两者带来的风险不同(即可能引发不同种类的错误),C语言的强制类型转换形式对这些不同并不加以区分。
-
将多态基类指针转换成派生类指针时不检查安全性,即无法判断转换后的指针是否确实指向一个派生类对象。
-
难以在程序中寻找到底什么地方进行了强制类型转换。
强制类型转换是引发程序运行时错误的一个原因,因此在程序出错时,可能就会想到是不是有哪些强制类型转换出了问题。
2. 强制转换运算符
C++ 引入了四种功能不同的强制类型转换运算符以进行强制类型转换:
-
const_cast
-
static_cast
-
reinterpret_cast 较少使用
-
dynamic_cast 虚函数中用的比较多
利用C++提供的运算符,就可以从编译器的角度上,最大的去支持检测安全性,鲁棒性更强。
3.const_cast
仅用于进行去除 const 属性的转换
,它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。
3.1 常用方法:利用const_cast 转换为同类型的非 const 引用或者指针
- <>内为转换的目标,()内为要转换的值
- const_cast只针对指针、引用、this指针
#include <iostream>
#include <string>
int main() {
const int n = 5;
const std::string s = "Inception";
//<>内为转换的目标,()内为要转换的值
//const_cast只针对指针、引用、this指针
int* k=const_cast<int*>(&n);//指针
*k = 123;
int& kRef = const_cast<int&>(n);//引用
kRef = 456;
}
下面为利用const_cast进行强制转换,利用指针和引用改变n的值的方法
3.2 常成员函数中去除this指针的const属性
3.2.1 常成员函数不能修改成员变量的值
//常成员函数,不能修改成员变量的值
void foo(int nTest) const {}
运行结果如下:
3.2.2 为什么常成员函数不能修改成员变量的原因
先复习一下,之前学过的const的使用:
const int* p;//代表指针指向的内容是不变的
int =5;
int* const p=&n;//代表p本身的值(地址)不可以该表
class CTest
{
public:
CTest() : m_nTest(2) {}
//常成员函数,不能修改成员变量的值
void foo(int nTest) const {
void* p = this;
//m_nTest = nTest;
//m_nTest = nTest; 错误
//const_cast<CTest*>(this)->m_nTest = nTest;
}
public:
int m_nTest;
};
int main() {
CTest t;
t.foo(1);
}
运行结果如下:
const在类的前面,代表指针指向的内容是不变的,也就是类的成员变量是不可以改变的。
3.2.3 可以通过const_cast去除类前面的const属性
//<CTest* const>指针地址不可改变,(this)代表常成员函数的this指针
//const_cast去除CTest*前面的const
const_cast<CTest* const>(this)->m_nTest = nTest;
#include <iostream>
#include <string>
class CTest
{
public:
CTest() : m_nTest(2) {}
//常成员函数,不能修改成员变量的值
void foo(int nTest) const {
//void* p = this;
//m_nTest = nTest;
//m_nTest = nTest; 错误
//<CTest* const>指针地址不可改变,(this)代表常成员函数的this指针
//const_cast去除CTest*前面的const
const_cast<CTest* const>(this)->m_nTest = nTest;
}
public:
int m_nTest;
};
int main() {
CTest t;
t.foo(1);
}
4.学习视频地址:强制转换const_cast
5.学习笔记:强制转换const_cast笔记
最后
以上就是义气钻石为你收集整理的C++新特性06_强制转换const_cast(const、强制转换、内存中?代表不可访问)的全部内容,希望文章能够帮你解决C++新特性06_强制转换const_cast(const、强制转换、内存中?代表不可访问)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复