C++类型转换
C语言类型转换
在c语言中,存在两种类型转换,一种是隐式类型转换,另一种是显示类型转换。
如下所示。
int a = 4;
double b = a; //隐式类型转换
int *ptr = &a;
int address = (int) ptr;
缺陷:
- C语言中的隐式类型转换看起来是很方便,但在有些时候也会给我们带来一些隐患问题。
- C语言中的强制类型转换太过于“笼统”,它可以使任意类型之间进行转换,但是不同类型间的差异还是蛮大的,但是它没有明确的区分。其次,它的转换的可视性很差,所有转换的形式都是一样的,一旦发生错误,我们很难去查找。
C++类型转换
C++为了增强转换的可视性,引入了四种强制转换的操作符分别是static_cast、const_cast、dynamic_cast、reinterpret_cast。
static_cast
static_cast 从字面意思来看叫做 “静态转换” ,它常用于内置类型之间的类型转换,也是最常用的类型转换,但它不能用于两个不相关的类型之间的转换。
double a = 5.67;
int b = static_cast<int> (a);
reinterpret_cast
reinterpret_cast 从字面意思来看叫做 “重新解释类型”,它可以用于内置类型的相互转换,也可以将内置类型转换为其他类型,其机理是"对二进制进行重新解释",不会改变之前的格式,通常用于将一种类型转换为另一种不同的类型。
int a = 0x0018ff44;
int* b = static_cast<int*>(a); //编译失败!
int* c = reinterpret_cast<int*>(a); //编译成功!
const_cast
const_cast,从字面上来看就知道是"const类型转换"的.它可以将const变量转换为非const属性,或者,将非const变量转换为const变量.不能用于不同类型变量转换!!!
const int a = 10;
int b = (int)a; //C语言类型转换
int c = const_cast<int>(a); //C++类型转换
dynamic_cast
dynamic_cast,从字面上来理解"动态类型转换".它用于派生类与基类之间的转换(主要将基类指针或引用转换为派生类指针或引用),转换时会进行类型安全检查.
Base *pBase = new Base();
Derive *pDerive = dynamic_cast<Derive*>(pBase);
注:
- dynamic_cast只能用于含有虚函数的类
- dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
explicit关键字
C++规定:对于可能只需传一个参数的默认构造函数,都定义了一种隐式调用。注意:只需传一个参数不仅指的是只有一个参数的默认构造函数,也指那些包含了定义了参数默认值的那些默认构造函数。
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 tmp(1); A a2(tmp);
A a2 = 1;
}
隐式类型转换表面上看给我们带来了很大的方便,但是实际上很多时候却会给我们代码埋下很深的隐患.通过关键字explicit,在声明构造函数的时候前面添加上explicit即可,当构造函数前加了explicit关键字后,原本代码中发生隐式转换的地方现在在编译的时候不能通过,这样,也就防止了我们程序中可能出现的问题。