赞
踩
目录
适用与两个相关的类型之间的自动转换,类型不相关时编译器会识别出来并报错。
- double a = 3.14;
- int b = a;//隐式类型转换
-
- int* p = nullptr;
- b = p;//两个不相关的类型无法进行隐式类型转换
如果想让两个不相关之间的类型发生转换,此时需要显示的取强制类型转换。
- int d = 3;
- int *pd = nullptr;
- d = (int)pd;//强制类型转换
1、转换的格式很简单。
2、转换的可视性较差。
3、没有错误检查,容易出错。
为了解决C语言类型的转换的问题,C++引入了四种命名的强制类型转换操作符。
static_cast用于非多态类型的转换,负责相关连的两个类型之间进行类型转换,与C语言中的隐式类型转换类似。
- double val1 = 3.3;
- int val2 = static_cast<int>(val1);//用于两个相关类型的转换
注意:
强制转换,用于两个不相关的类型的转换,简单来说什么类型都可以转,这种转换不对结果做保证,容易出问题。
- typedef void(*fuc)(void);
- void* test(int num)
- {
- cout << "test: " << num << endl;
- return nullptr;
- }
- int main()
- {
- fuc val3 = reinterpret_cast<fuc>(test);//把一个void*返回值、int类型的参数的函数转换成ret = void和参数为void的函数
- val3();
- }
运行结果难以预料。
注意:
去除变量的常属性,只针对指针和引用。
- const int a = 3; //常变量
- int* pa = &a; //这样将a的地址赋值给pa是错的,因为a的地址是const int*类型
-
- //此时可以采用const_cast 来进行强转
- const int a = 3;
- int* pa = const_cast<int*>(&a);//此时可以把const int* 转换成int*
补充:如果此时对pa指向的空间修改同时打印a 的值和 *pa的值会发生什么
- *pa = 4; // pa指向的空间更改
- cout << a << endl; //输出3 编译器的优化,默认从寄存器读取,此时采用volatile关键字修饰
- cout << *pa << endl; //输出4
可以看到a的值确实改变,但为什么会输出3呢?
原因:编译器的优化。
编译器会默认的认为常变量是不会被修改的,所以会将他的值拷贝到寄存器当中,每次获取a的值都是从寄存器中去获取,而不是从内存中读取。常变量a他在内存中的栈区间内,这个a的值是已经被修改了。
如果要避免这种情况的发生,需要用关键字volatile,他的作用是防止编译器去优化,每次读取数据从内存中读取数据。
用于类的向上向下转换。
向上转换:子类向基类转换。
向下转换:基类向子类转换。
前提:dynamic_cast只能用于含有虚函数的类。
dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0。
- class Base
- {
- public:
- virtual void functon(void){}
- int a;
- };
- class Child :public Base
- {
- public:
- int b;
- };
- void test(Base* ptr)
- {
- Child* pc1 = (Child*)ptr;//C语言中的强转
-
- Child* pc2 = dynamic_cast<Child*>(ptr);//C++中的转换,会判断是否能够转换成功
-
- cout << "pc1: " << pc1 << endl;
- cout << "pc2: " << pc2 << endl;
-
- }
- //main函数
- Base b;
- Child c;
-
- test(&b);//给一个基类的地址
- test(&c);//给一个子类的地址
向下转换是一个很不安全的过程,转换的时候会进行类型检查,类型相等成功转换,类型不等转换失败。但是C语言中的强转不管结果怎样,很危险。
如果传入一个基类的地址进去的时候,强转之后 如果此时访问一下子类的成员,会出现错误。
1、转换明确,调用什么样的类型转换一眼便知道
2、可以进行错误检查。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。