C++中的类型转换

来源:互联网 发布:linux服务总结 编辑:程序博客网 时间:2024/06/05 07:27

我们知道:变量的类型定义了对象能包含的数据和参与的运算。其中一种运算被大多数类型支持,就是将变量从某一种给定的类型转化为另外的类型。


在了解类型转换种类之前,首先牢记:类型转换只是暂时的,原来的变量类型并不改变。


在C语言中,分为两种类型转换

1,隐式类型转换

2,显示类型转换

例如:

double d = 12.34;int i = d;//发生隐式转化int* p = (int*)&double;//发生强制转换


在C++中,标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:

1,static_cast

static_cast用于非多态类的转换(类似于静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。

例如:

int i = 0;double d = static_cast<double>(i);

2,reinterpret_cast

reinterpret_cast用于reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。

例如:

typedef void (*Fun_1)();int Fun_2(double d){...}Fun_1 f  = reinterpret_cast<Fun_1>(Fun_2);//将Fun_2的位模式重新解释为Fun_1的位模式,使得编译通过。f();//按照Fun_1的规范调用函数
注:C++不能保证所有的函数指针都被一样的使用,所以有时会产生不确定的结果。

3,const_cast

const_cast最常用的用途就是删除变量的const属性,方便赋值。

确切的说,const_cast去掉的是底层const的属性。即只改变指针或引用的const属性,不改变对象本身的const属性。

例如:

void fun1(int a){}//参数类型不同,const的种类不同void fun2(int& a){}//参数类型不同,const的种类不同int main(){    const int a = 10;    fun1(a);//不会报错,因为此时const是顶层const    fun2(a);//会报错,因为此时const是底层const}
此时,通过const_cast即可。

fun2(const_cast<int&>(a));


4,dynamic_cast

dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)

向上转型:子类对象指针->父类指针/引用(不需要转换)

向下转型:父类对象指针->子类指针/引用(用dynamic_cast转型是安全的)

1.  dynamic_cast只能用于含有虚函数的类。

2.  dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0。

例如:

class Base{public :virtual void fun(){}};class Derived:public Base{};int main(){Base* pb = new Derived();//编译成功Derived* pd = new Base();//编译失败(说明使用static_cast也不行)return 0;}
此时,需要使用dynam_cast来强制转换。

Derived* pd = dynamic_cast<Derived>(new Base());


另外:对于类来说,当满足:1,类中成员变量只有一个(单参)2,没有被expli修饰。

如果我们使用拷贝形式的初始化(使用=)时,会发生隐式转换,编译器用给定的左值自创建一个该类的对象,将这个临时变量传给需要初始化的类。

例如:

class A{public :    A(int a):i(a){};    int i;}A a = 20;//此时会发生隐式转换

编译器会通过20创建一个类中变量i为20的临时类,将临时类传给a,会调用默认或自己写的拷贝构造函数。这种情况就是使用拷贝形式的初始化。

当我们在构造函数声明前加上explicit关键字时,该构造函数只能用于直接初始化。即

A类中:explicit A(int a):i(a);
A a2(a1);//直接初始化

这样可以避免一些不合时宜的隐式转换。


0 0