您的位置:首页 > 编程语言 > C语言/C++

使用C++转型操作符(More Effective_C++_2(基础))

2015-08-18 21:50 429 查看
一、c语言中的类型转换表达式:

(1)
(type) expression


(2)
type (expression)


上面两种形式并无差别,只是小括号位置不同,我们称之为“旧式转型”;

注:几乎允许你将任何类型转换成任何其他类型,另外一个问题是它们难以辨识,因为小括号加上一个对象名,在C++任何地方都有可能被使用

二、C++中新式转型操作符(cast operator)

2.1 static_cast

(1)表达式
static<type>(expression)


(2)static_cast基本上拥有与C旧式转型相同的意义与限制,不能移除表达式的常量性等等(转换常量性const_cast实现)

(3)可以将static_cast理解为实现旧式转型的功能

(4)例子:假设你想要将一个int转换为一个double,可以将non-const转换为const对象

采用旧式转型可以这么做:
int num1,num2;
double result=((double)num1)/num2;
采用新式转型,应该这么写:
double result=(static_cast<double>num1/num2);
这种方式更容易辨识出来


2.2 const_cast

(1)const_cast用来改变表达式的常量性或变易性,用于上述以外的用途,那么转型会失败

(2)const_cast**最常见的用途,就是将某个对象的常量性去掉**

(3)例子:

class A{...};
class B:public A{...};
void set(B* x);
B x1;//x1是个非常量对象
const B& x2=x1;//x2代表x1的一个引用,并且是一个常量对象

set(&x2);//错误,不能将一个const B*传给一个需要B*的函数
set((const_static<B*>(&x2)));//正确,常量性被去掉了
set((B*)(&x2));//情况同上,但是使用的是辨识度低的旧式转型语法;

A *y=new B;
set(y);//错误,y的类型是A*,但是set()需要的确是B*
set(const_cast<B*>(y));//错误,const_cast只能用来改变常量性或变易性,无法进行继承体系的向下转型操作


2.3 dynamic_cast

(1)用来执行继承体系中的向下类型(即基类向派生类转换)或跨系转型操作,也就是说可以将指向基类对象的指针或引用,转为指向派生类对象的指针或引用

(2)如果转型失败,会以一个NULL指针(当转型对象是指针)或者是一个异常表现出来(当转型对象是引用)

(3)只能应用在继承体系之中,无法应用在缺乏虚函数的类型身上,也不能改变类型的常量性

(4)如果想为一个不涉及继承机制的类型执行转型动作,可以使用static_cast,要改变常量性,则必须使用const_cast

(5)例子:

int num1,num2;
double result=((double)num1)/num2;
double result=(dynamic_cast<double>num1/num2);//错误,没有涉及继承机制


2.4 reinterpret_cast

(1)最常用的用途是转换成函数指针类型

(2)该转型操作,并不具有移植性(C++不保证所以的函数指针都能以此方式重新呈现),某些情况下会导致不正确的结果,所以我们应该尽量避免函数指针转型

(3)例子

typedef void(*fun)();//fun是个函数指针,指向某个函数,返回值是void
fun funArray[10];//funArray是个数组,内有10个fun;
假如你想将下面的函数的一个指针放进funArray中:
int dosomething();

funArray[0]=&dosomething;//错误,类型不符;
funArray[0]=reinterpret_cast<fun>(&dosomething);//正确


三、尽量少做转型动作(Effective C++_27)

(1)如果可以,尽量避免转型,特别是在注重效率的代码中避免使用dynamic_cast

2.如果必须要转型,请试着将其隐藏在某个函数背后

3.宁可使用C++新型的转换,不用旧式转型

参考:more effective C++(侯捷译)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: