一、什么是强制类型转换?
简单来说强制类型转换就是将某一类型的变量强转成另一种类型的变量。
二、C语言中的强制类型转换?
1.隐式类型转换:所谓隐式,就是我们没有写出来,而是编译器自己去识别。需要注意的是,隐式类型转换只能转换相近类型的,比如int/char/double这些都可以隐式类型转换,但对于int和int*这种不相关的类型就需要强制类型转换。
2.显式类型转换:对于不相关类型,需要进行显式的强制类型转换。如int和int*等。
int a=10;
double b=20.0;
int* pa=&a;
a=b;//相近类型,将double类型隐式转换成int类型
//int j=p;//int和int*不是相关类型,不能隐式转换
int j=(int)p;//不相关类型,显式强制转换
三、C++四种强制类型转换?
1.static_cast:1>相关类型的隐式类型转换,编译器隐式执行的所有类型转换都可以用static_cast,对应C语言的隐式类型转换。
2>用于非多态的类型转换(静态转换)。
//相关类型的转换
int i = 10;
double d = static_cast<double>(i);
2.reinterpret_cast:1>不相关类型变量之间的转换。对应C语言中的显示强制类型转换。
2>用于非多态的类型转换(静态转换)。
//不相关类型的转换
int i = 10;
int* p = &i;
int j = reinterpret_cast<int>(p);
3.const_cast:1>去掉变量的const属性,方便给const变量赋值。是不相关类型转换细分的一种。
2>用于静态的强制类型转换。
const int i = 10;
int* j = const_cast<int*>(&i);//&a的类型:const int*/int const*
*j = 20;
cout << i << endl;//10
cout << *j << endl;//20
volatile const int i = 10;
int* j = const_cast<int*>(&i);&a的类型:const int*/int const*
*j = 20;
cout << i << endl;//20
cout << *j << endl;//20
4.dynamic_cast:1>用于将一个父类对象的指针或引用转换为子类对象的指针或引用(动态转换)。
2>涉及继承,只能用于包含虚函数构成多态的类,不是虚函数会报错。
3>dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0。
class A
{
public:
int _a;
virtual void f()
{}
};
class B :public A
{
public:
int _b;
};
void fun(A* pa)
{
//使用static_cast转换:
//如果是派生类指针转换则没问题;
//如果是基类指针通过强制转换虽然会成功,但是可能会造成越界访问的问题,如pb1->_b=20;
B* pb1 = static_cast<B*>(pa);
cout << "pb1:" << pb1 << endl;
//使用dynamic_cast转换:
//如果是派生类指针转换则没问题;
//如果是基类指针则转换失败,返回0;
B* pb2 = dynamic_cast<B*>(pa);
cout << "pb2:" << pb2 << endl;
}
void Test()
{
A a;
B b;
fun(&a);//基类
fun(&b);//派生类
}
输出结果:
四、explicit关键字:
阻止经过转换构造函数进行的隐式转换的发生,只能阻止具有单参数构造函数类的隐式类型转换。
如下:正常情况下C c2=20,先用20构造一个C类对象,然后给c2,用explicit修饰构造函数后,不能这样做。
class C
{
public:
explicit C(int a)
:_a(a)
{
cout << "C(int a)" <<_a << endl;
}
C(const C& c)
:_a(c._a)
{
cout << "C(const C& c)" <<_a << endl;
}
private:
int _a;
};
void Test3()
{
C c1(10) ;
//C c2 = 20;//编译不通过
}
五、为什么需要C++需要四种类型转换:
弥补C语言类型转换的缺点
1. 隐式类型转化有些情况下可能会出问题。
2. 显式类型转换将所有情况混合在一起,代码不够清晰 。
注意 :强制类型转换关闭了正常的类型检查,每次使用强制类型转换前,应考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换,则应限制强制转换值的作用域,以减少错误。建议:避免使用强制类型转换。