目录
一、static_cast
在内置的数据类型之间互相转换,对于类只能在有联系的指针类型间进行转换
1.用于基本类型间的转换,如把int转换成char,把int转换成enum
enum WeekType {sun=0,mon=1,tues=2};
int main()
{
WeekType wt=sun;//wt的范围sun=0,mon=1,tues=2
sizeof(WeekType);//4
int x=0;
int a=97;
x=wt;//范围小的给大的
x=10;
wt=static_cast<WeekType>(x);//并不会进行检查,x的值大于wt的值,但是仍能进行类型转换
}
2.不能用于基本类型指针之间的转换
指针转换的限制:类型与将要赋值的类型保持一致,不允许在不同类型间进行转换,可以将普通指针给常性指针
int main()
{
int a=10;
int *p=&a;
int *s=static_cast<int *>(&a);
const int *cp=&a;
cp=static_cast<int *>(&a);//ok
s=static_cast<int *>(cp);//error cp是常性,不允许将cp的常性去掉给s
s=(int *)cp;//ok
}
3.在模板里面我们可以进行使用,可以检查模板类型是否一致,一致通过,不一致报错
//在模板里面,我们可以确定原和目标是否一致
template<class T,class U> //T int, U char
void func(T *p,U *s)
{
p=static_cast<T *>(s);//报错
}
int main()
{
int a=10,b=20;
char ch='a';
func(&a,&ch);
return 0;
}
4.可以就void*转换为其他类型
class Int {
};
int main() {
int a = 10;
char ch = 'c';
Int ia;
void* vp = NULL;
vp = &a;
int* ip = static_cast<int*>(vp);
char *cp= static_cast<char*>(vp);
vp = &ch;
vp = &ia;
}
5.弃值表达式
int add(int a, int b) {
cout << "add" << endl;
return a + b;
}
int main() {
int x = 10, y = 20;
static_cast<void>(add(x, y));//调用了add函数,但是将函数的返回值舍弃
}
6.可以将左值转换为右值(常性左值不允许转换为右值)
class Int {
private:
int value;
public:
Int(int x = 0) :value(x) {}
~Int(){}
int GetValue() const { return value; }
void SetValue(int x) { value = x; }
};
int main() {
int a = 10;
int& ra = a;
int&& rb = static_cast<int&&>(a);
Int ia(10);
Int& ria = ia;
Int&& rib = static_cast<Int&&>(ia);
}
7.用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的
注意:
隐式执行任何类型转换都可由static_cast显示完成
static_cast不能转换掉expression的const,volatile,或者_unaligned属性
二、const_cast
1.用于去除变量的只读属性
拿const修饰的基本数据类型(对于自己设计的类型并没有替换一说)编译时并不会直接从内存中取,而是直接进行替换
int main()
{
const int a=10;//在编译阶段遇到的a都使用10进行替换
const int* cp=&a;
const int& cr=a;
int *p=const_cast<int *>(cp);
int &r=const_cast<int &>(cr);
int &&rr=const_cast<int&&>(a);
return 0;
}
2.强制转换的目标类型必须是指针或引用
常量指针被转化成非常量的指针,并且仍然指向原来的对象;
常量引用被转换成非常量的引用,并且仍然引用原来的对象;
三、reinterpret_cast
用法:reinterpret_cast<type_name>(expression)
type_name必须是一个指针、引用、算法类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。类似于C语言的强转
四、dynamic_cast
支持PTTI类型转换,通常在基类和派生类之间转换时使用
dynamic_cast转换符只能用于指针或者引用。dynamic_cast转换符只能用于含有虚函数的类。dynamic_cast转换操作符在执行类型转换时首先将检查能否成功转换,如果转换失败,T是指针则反回一个nullptr,如果是转换的是T引用,则抛出一个bad_cast异常