在学习c++类型转换之前,我们要先看一下c语言时学习的类型转换。c语言学过两种类型转换:
- (1)隐式类型转换
- (2)显示的强制类型转换
void Test()
{
int i = 1;
//隐式类型转换
double d = i;
printf("%d,%.2f\n",i,d);
int* p = &i;
//显示的强制类型转换
int address = (int)p;
printf("%x,%d\n",p,address);
}
c语言类型转换的缺陷是:转换的可视性较差,所以的类型转换都是以一种相同形式书写,难以跟踪错误的转换
c++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符
static_cast、reinterpret_cast、const_cast、dynamic_cast
一.static_cast
static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型的转换都可用static_cast;例如:非const转const,void* 转指针等,但是它不能用于两个不相关的类型进行转换。
int main()
{
double d = 12.34;
int a = static_cast<int>(d);
cout << a <<endl;
return 0;
}
二.reinterpret_cast
reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于一种类型砖混啊为另一种不同的类型。
几乎什么都可以转,比如将int转指针,可能会出现问题,尽量少用。
typedef void (* FUNC)();
int DoSomething(int i)
{
cout << "DoSomething" <<endl;
return 0;
}
void Test()
{
//
FUNC f = reinterpret_cast<FUNC>(DoSomething);
f();
}
三,const_cast
const_cast最常用的用途就是删除变量的const属性,方便赋值。
void Test()
{
const int a = 2;
int* p = const_cast<int *> (&a);
*p = 3;
cout << a << endl;
}
四.dynamic_cast
- (1)用于动态的类型转换,只能用于含有虚函数的类,用于类层次间的向上和向下转换。只能转指针或引用。向下转化时,如果时非法的对于指针返回nullptr,对于引用抛异常。要深入理解内部转换的原理。
- (2)向上转换:指的是子类向基类的转换
- (3)向下转换:指的是基类向子类的转换。
- (4)它通过判断在执行到该语句的时候变量的运行时类型和要转换的类型是否相同来判断是否能够进行向下转换。
- (5)dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)
class A
{
public:
virtual void f(){}
};
class B : public A
{};
void fun(A* p)
{
// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
B* p1 = static_cast<B*>(p);
B* p2 = dynamic_cast<B*>(p);
cout << "p1:" << p1 << endl;
cout << "p2:" << p2 << endl;
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}
五.explicit
explicit关键字阻止经过转换构造函数进行的隐式类型转换的发生。
class A
{
public:
explicit A(int a)
{
cout << "A(int a)" << endl;
}
A(const A& a)
{
cout << "A(const A& a)" <<< endl;
}
private:
int _a;
};
int main()
{
A a1(1);
//隐式类型转换
A a2 = 1;
}