- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
1. static_cast
static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换。
1.1 语法
static_cast<new_type>(expression)
1.2 使用场景
static_cast没有运行时类型检查,因此不安全。
- 用于类层次结构中基类和派生类之间指针或引用的转换。
struct B {
int m = 0;
void hello() const {
cout << "B::hello()" << endl;
}
};
struct D : B {
void hello() const {
cout << "D::hello()" << endl;
}
};
void main() {
D d;
B& br = d; //upcast via implicit convertion
br.hello();
D& dr = static_cast<D&>(br); //downcast
dr.hello();
}
- 用于基本数据类型之间的转换
int n = static_cast<int>(3.14);
- 把void类型指针转换成任意类型指针
int n = static_cast<int>(3.14);
void *nv = &n;
int *ni = static_cast<int*>(nv);
2. dynamic_cast
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。
2.1 语法
dynamic_cast<new_type>(expression)
2.2 使用场景
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
- 类层次间向下转换
#include<iostream>
using namespace std;
struct Base {
virtual ~Base()
{
}
};
struct Derived :Base {
virtual void name() {
cout << "Derived::name" << endl;
}
};
void main() {
Base* b1 = new Base;
if (Derived* d = dynamic_cast<Derived*>(b1)) {
cout << "Downcast from b1 to d successful" << endl;
d->name();
}
Base* b2 = new Derived;
if (Derived* d = dynamic_cast<Derived*>(b2)) {
cout << "Downcast from b2 to d successful" << endl;
d->name();
}
delete b1;
delete b2;
system("pause");
}
3. const_cast
const_cast用于修改类型的const或volatile属性。
3.1 语法
const_cast<new_type>(expression)
3.2 使用场景
- 常量指针被转化为非常量指针,并且仍然指向原来的对象
const int i = 10;
int *pi = const_cast<int*>(&i);
struct Type
{
int i;
Type():i(3){}
void f(int v) const {
//this->i = v; //compile error: this is a pointer to const.
const_cast<Type*>(this)->i = v;
}
};
- 常量引用被转化为非常量引用,并且仍然指向原来的对象
const int i = 10;
int &ri = const_cast<int&>(i);
4. reinterpret_cast
reinterpret_cast可以支持将一种指针类型转换为另一种指针类型,不管两者之间有没有任何关系。reinterpret_cast并不会进行类型检验。因此需要慎用。
4.1 语法
static_cast<new_type>(expression)
data_type *var_name = reinterpret_cast <data_type *>(pointer_variable);
new_type必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以将一个指针转换为一个整数,也可以把整数转换为一个指针。
4.2 使用场景
- 将指针转换为一个整数,将整数再转换回指针
int i = 7;
//Convert int ptr to a unsigned integer
uintptr_t v1 = reinterpret_cast<uintptr_t>(&i);
cout << "The value of &i is 0x" << std::hex << v1 << endl;
int *p1 = reinterpret_cast<int*>(v1);
assert(p1 == &i);
- 将一种指针类型转换为另一种指针类型
struct S
{
int x;
};
struct T {
int x;
int f() {
cout << "T::f()" << endl;
return 1;
}
};
void main() {
S s = {};
auto p = reinterpret_cast<T*>(&s);
p->x = 20;
auto i = p->x;
p->f();
cout << i << endl;
}
网友评论