C++小知识——C++的四种类型转换方式

这里有两篇文章写的很好,还举了例子
http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html
http://www.cnblogs.com/goodhacker/archive/2011/07/20/2111996.html

一、什么是类型转换

通过改变一个变量的类型为别的类型,进而改变该变量的表示方式,这就是类型转换


二、传统的C风格转换

例如
int i;
double d;
i = (int)d;
或者
i = int(d);

有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,
比如你可以把一个指向const对象的指针转换成指向非const对象的指针,
把一个指向基类对象的指针转换成指向一个派生类对象的指针,
这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。
还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,
而这样的东西在c++程序里一大堆。所以c++为了克服这些缺点,引进了4新的类型转换操作符。


三、四种新的类型转换符

reinpreter_cast<type-id> (expression)
static_cast<type-id> (expression)
dynamic_cast<type-id> (expression)
const_cast<type-id> (expression)

1)reinterpret_cast:仅仅重新解释类型,但没有进行二进制的转换。

reinterpret_cast转换一个指针为其他类型的指针,也允许一个指针转换为整型,反之亦然
reinterpret_cast能够在不相关的类型之间转换,比如int指针转为char指针
操作结果只是简单地从一个指针到别的指针的值的二进制拷贝
在类型之间指向的内容不做任何类型的检查和转换
reinterpret_cast就像传统的类型转换一样对待所有指针的类型转换

class A{};
class B{};

A *a = new A;
B *b = reinterpret_cast<B*>(a);

2)static_cast:命名上理解是静态类型转换,如int转换成char。

static_cast允许执行任意的隐式转换和相反转换动作

可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等)
还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针)
但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它是最接近于C-style的转换

1)用于基本数据类型之间的转换,如把int转换成char,non-const 对象转型为 const 对象(这里相反方向不可以,C++只有const_cast可以)。

2)把空指针转换成目标类型的指针。(之前的做法是用强制转换(type-id*))

3)把任何类型的表达式转换成void类型。

4)应用到类的指针上,
它允许子类类型的指针转换为父类类型的指针(这是有效的隐式转换);
同时,也允许父类类型的指针转换为它的子类类型的指针

class Base {};
class Derived : public Base {};

Base *a    = new Base;
Derived *b = static_cast<Derived *>(a);

也可以用于执行类型定义的显式的转换,以及基础类型之间的标准转换

double d = 3.1415926;
int    i = static_cast<int>(d);
std::cout << i;	// 3

3)dynamic_cast:命名上理解是动态类型转换,如子类和父类之间的多态类型转换。

dynamic_cast 主要用于执行“安全的向下转型”,不能用于内置的基本数据类型的强制转换。

其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查

dynamic_cast只用于对象的指针和引用

当用于多态类型时,它允许任意的隐式类型转换以及相反过程。
不过,与static_cast不同
在隐式转换的相反过程中,dynamic_cast会检查操作是否有效
如果被转换的指针不是一个被请求的有效完整的对象指针(转换失败),返回NULL

类层次间进行向上转换时,和dynamic_cast和static_cast是一样的
用于继承体系中的向下转型,即将基类指针转换为派生类指针,比static_cast更严格更安全,但牺牲了效率

使用dynamic_cast进行转换时,基类中一定要有虚函数,否则编译不通过

class Base{
public:
    virtual dummy(){}
};
class Derived:public Base{};

Base* b1 = new Derived;
Base* b2 = new Base;

Derived* d1 = dynamic_cast<Derived>(b1);	//成功
Deriver* d2 = dynamic_cast<Derived>(b2);	//失败,返回NULL

4)const_cast:字面上理解就是去const属性。

const_cast用于修改类型的const或volatile属性,或者是设置或者是移除
其他三种操作符是不能修改一个对象的常量属性的

常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;
常量对象被转换成非常量对象。

const_cast只有const类型的变量才能使用
比如,有时候有的函数的形参类型为非const类型,那么如果你要将一个const类型的参数传入就会报错。
所以在这种情况下需要先使用const_cast转化一下

class C {};
const C *a = new C;
C *b = const_cast<C *>(a);

使用
在这里插入图片描述


总结

去const属性用const_cast;
基本类型转换用static_cast;
多态类之间的类型转换用dynamic_cast;
不同类型的指针类型转换用reinterpret_cast;
四种类型转换操作符对于隐式的类型转换没有必要。

猜你喜欢

转载自blog.csdn.net/CSDN_dzh/article/details/84557306
今日推荐