文章目录
(***)1. 类型转换
c语言的转换;
(1)隐式转换(从表示范围小的类型转化为范围大的类型)
(2) 显示类型转化:强制类型转化;
void*v = p; //1.1 隐式转换
p = (int*) v; //1.2显示类型转化;
xxx_cast <类型> (表达式)
一共有以下四种形式: static_cast
, const_cast
, dynamic_cast
,
reinterpret_cast
,提供安全性的检测,在代码中更加醒目;
(***)1.1. static_cast
用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。
主要有如下
- 基本数据类型转换
int
转换成enum
- 基类和子类之间指针和引用的转换
- 上行转换,把子类的指针或引用转换成父类,这种转换是安全的(通常使用默认转换)。
- 下行转换,把父类的指针或引用转换成子类,这种转换是不安全的,也需要程序员来保证(通常使用
dynamic_cast
)。
1.1.1 基本数据类型转换
int
转换成char
char c = 'a';
cout << c << endl;
cout << (int)c << endl;
cout << static_cast<int>(c)<< endl;
1.1.2 int
转换成enum
enum BOOL{
FALSE,TRUE
};
BOOL b = static_cast<BOOL>(1==2);
编译上述代码出现如下错误:
- g++编译错误:
error: invalid conversion from ‘int’ to ‘Week’
- clang++编译错误:
error: cannot initialize a variable of type 'const Week' with an rvalue of type 'int'
把代码Week day = 0;
改为Week day = static_cast<Week>(0);
可以消除上面的错误。
1.1.3 指针/引用转换
void
指针转换成目标类型的指针,这种转换是不安全的,也需要程序员来保证;
如下代码编译出错,因为不能把void*
转换成其他具体指针。
//2.2指针类型之间的转化;(pointer)
int* arr1 = (int*)malloc(10*sizeof(int));
int* arr2 = static_cast<int*>(malloc(10*sizeof(float)));
(完整代码见001_static.cpp)
#include <iostream>
using namespace std;
enum BOOL{
FALSE,TRUE
};
int main()
{
//1 c语言的转换;
//1.1 隐式转换(从表示范围小的类型转化为范围大的类型)
//1.2 显示类型转化:强制类型转化;
int n = 10;
float f = n;
n = f; //截取
int* p = &n;
void*v = p; //1.1 隐式转换
p = (int*) v; //1.2显示类型转化;
//2.1基本类型之间的转化;
char c = 'a';
cout << c << endl;
cout << (int)c << endl;
cout << static_cast<int>(c)<< endl;
//2.2指针类型之间的转化;(pointer)
int* arr1 = (int*)malloc(10*sizeof(int));
int* arr2 = static_cast<int*>(malloc(10*sizeof(float)));
//2.3 bool类型的转化;
BOOL b = static_cast<BOOL>(1==2);
cout << b << endl;
return 0;
}
把Base* pb = pd;
改为Base* pb = static_cast<Base*>(pd);
,可以解决上述编译错误。
static_cast
跟传统小括号转换方式几乎是一致的。
问题:为什么要用static_cast
代替传统小括号转换方式?
(***)1.2. const_cast
常量赋值给非常量时,会出现下面编译错误。
const int a = 10;
// 指针
const int* cp = &a;
int* p = cp;// error: invalid conversion from ‘const int*’ to ‘int*’
// 引用
const int& cf = a;
int& f = cf;// error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers
const_cast
主要作用是移除类型的const
属性。
- 常量指针被转化成非常量的指针,并且仍然指向原来的对象;
- 常量引用被转换成非常量的引用,并且仍然指向原来的对象;
const_cast
一般用于修改底指针。如const char *p
形式。
const int a = 10;
// 指针
const int* cp = &a;
int* p = const_cast<int*>(cp);
// 引用
const int& cf = a;
int& f = const_cast<int&>(cf);
(***)1.2.1 在const
成员函数中修改基本类型
const_cast<>
在<>
中通常只用指针或者引用类型。- 基本类型常量,因为存在常量展开的情况,
const_cast<>
并不会改变后面的值。
(1) 基本类型
<>里面不能用在基本类型,只能用指针和引用;;
基础类型onstc常量在使用展开操作,类似于在宏定义的展开(即a的值不变,但是内存的值改变啦)
const int a = 10;
//const_cast<int> a = 11; //(1.1)<>里面不能用在基本类型,只能用指针和引用;
const_cast<int&>(a) = 12; //(1.2)引用修改
cout << &a << ":" << a << endl; //(1.3)基础类型onstc常量在使用展开操作,类似于在宏定义的展开(即a的值不变,但是内存的值改变啦)
(2)不能修改的字符串对象
const string s("abcd");
cout << s << endl;
const_cast<string&>(s) += "efg";
(3)不能修改的类的成员变量,返回引用和指针类型
const Simple s1(100);
cout << s1.Get() << endl;
const_cast<Simple&>(s1).Set(110);
cout << s1.Get() << endl;
const Simple* ps1 = &s1;
cout << ps1->Get() << endl;
const_cast<Simple*>(ps1)->Set(120);
cout << ps1->Get() << endl;
(完整代码见00201_const_cast.cpp)
#include