标准C++中为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符。
static_cast
reinterpret_cast
const_cast
dynamic_cast
为了更好的理解C++中的类型转换,我们先讲讲我们在C语言中的转换。
#include<iostream>
void test()
{
int i = 2;
double d = i;
printf("隐式类型转换:i = %d, d = %f\n ", i, d);
int *p = &i;
int address = (int)p;
printf("强制类型转换:p = %x,address = %d", p, address);
}
int main()
{
test();
return 0;
}
打印结果:
强制转换的可视性比较差,所有的转换形式都是以同一种相同形式书写,难以跟踪错误的转换。
C++中为了加强类型转换的可视性,引入了四种类型转换操作符
static_cast:
static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相干的类型进行转换
int main()
{
double d = 3.14;
int a = static_cast<int>(d);
std::cout << a << std::endl;
return 0;
}
//输出为3
reinterpret_cast:
用于将一种类型转换为另一种不同的类型。
typedef void(*FUNC)();
int dosomething(int i)
{
cout << "dosomething" << endl;
return 0;
}
void test()
{
FUNC f = reinterpret_cast<FUNC>(dosomething);
f();
}
int main()
{
test();
return 0;
}
//输出:desomething
const_cast:
const_cast最常用的用途就是删除变量的const属性,方便赋值。
void Test ()
{
const int a = 1;
int* p = const_cast< int*>(&a );
*p = 3;
cout<<a <<endl;
}
//输出:3
dynamic_cast:
dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或者引用(动态转换)
注意点:
1,dynamic_cast只能用于含有虚函数的类
2,dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
class A
{
public :
virtual void f()
{}
};
class B : public A
{};
void test (A* pa)
{
B* pb1 = static_cast<B*>(pa);
B* pb2 = dynamic_cast<B*>(pa);
cout<<"pb1:" <<pb1<< endl;
cout<<"pb2:" <<pb2<< endl;
}
int main ()
{
A a;
B b;
test(&a);
test(&b);
return 0;
}
打印为:
Explicit关键字
C++中的关键字explicit主要是用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。隐式转换即是可以由单个实参来调用的构造函数定义了一个从形参类型到该类类型的隐式转换。
一般只将有单个参数的构造函数声明为explicit,而拷贝构造函数不要声明为explicit。