C++四种类型转换

C++提供了四种新式类型转换(常常被称为new-style或C++-style casts):

const_cast<T>(exception)

static_cast<T>(exception)

dynamic_cast<T>(exception)

reinterpret_cast<T>(exception)

注意:强制类型转换干扰了正常的类型检查,因此,我们强烈建议程序猿避免使用强制类型转换。这个建议对于reinterpret_cast尤其试用,因为此类型转换总是充满了危险。

const_cast

通常被用来将对象的常量性移除(cast away the constness)。它也是唯一有此能力的C++style转型操作符。
const char* pc;
char *p=const_cast<char*>(pc);
const_cast常常用于有函数重载的上下文中。
class TextBlock{  
public:  
……  
const char& operator[](size_t position) const{  
……  
……  
return text[position];  
}  
char& operator[](size_t position){  
return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);//先添加const属性,再移除。  
}  
……  
};


dynamic_cast

主要用来执行安全向下转型(safe downcasting),也就是用来决定某对象是否归属继承体系中的某个类型。它是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。
运行时类型识别(run-time type identification,RTTI)的功能由两个运算符实现:
  • typeid运算符,用于返回表达式的类型。
  • dynamic_cast运算符,用于将基类的指针或引用安全的转换成派生类的指针或引用。
当我们将这两个运算符用于某种类型的指针或引用,并且该类型含有虚函数时,运算符将使用指针或引用所绑定对象的动态类型。
这两个运算符特别适用于以下情况:我们想使用基类对象的指针或引用执行某个派生类操作并且该操作不是虚函数。一般来说,只要有可能我们应该尽量使用虚函数。当操作被定义成虚函数时,编译器将根据对象的动态类型自动的选择正确的函数版本。
然而并非任何时候都能定义一个虚函数。假设我们无法使用虚函数,则可以使用一个RTTI运算符。另一方面,与虚成员函数相比,使用RTTI运算符蕴含着更多潜在风险:程序猿必须清楚的知道转型的目标类型并且必须检查类型转换是否被成功执行。
dynamic_cast运算符使用形式如下所示(type必须为一个类型,且通常情况下该类型应该含有虚函数):
dynamic_cast<type*>(e)          //e必须是一个有效指针
dynamic_cast<type&>(e)         //e必须是一个左值
dynamic_cast<type&&>(e)         //e不能是左值
在上面的形式中e的类型必须符合以下三个条件中的任意一个:e的类型是目标type的公有派生类、e的类型是目标type的公有积基类或者e的类型就是目标type的类型。如果符合则转型成功,否则转型失败。如果一条dynamic_cast语句的转换目标是指类型并且失败了,则记过为0.如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个bad_cast异常。



reinterpret_cast

意图执行低级转型,实际动作及结果可能取决于编译器,这也表示它不可移植。例如讲一个pointer to int转型为一个int。这一类转型在低级代码以外很少见。
int *ip;
char *pc=reinterpret_cast<char*>(ip);
我们必须牢记pc所指的真实对象时一个int而非字符,如果把PC当成普通的字符指针使用就可能在运行时发生错误。
string str(pc);//可能导致异常的运行时行为。
使用reinterpret_cast是非常危险的,用pc初始化str的例子很好地证明了这一点。其中的关键问题是类型改变了,但编译器没给出任何警告或者错误的提示信息。当我们使用一个int地址初始化pc时,由于现实的声称这种转换合法,所以编译器不会发出任何警告或错误信息。接下来再使用pc时就会认定它的值是char*类型,编译器没法知道它实际存放的是指向int的指针。最终结果就是,在上面的例子中虽然用pc初始化str没什么实际意义,甚至还可能引发更糟糕的后果,但仅从语法上而言这种操作无可指摘。查找这类问题的原因非常困难,如果将ip强制转换成pc的语句和用pc初始化为string对象的语句分数不同文件就更是如此。


static_cast

用来强迫隐式转型(implicit conversions),例如将non-const对象转为const对象,获奖int转为double等等。它也可以用来执行上述多种转换的反向转换,例如将void*指针转换为typed指针,将pointer-to-base转为pointer-to-derived。但是它无法将const转为non-const——这个只有const_cast才办得到。
也就是说,任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
//进行强制类型转换以便执行浮点数除法。
double slope=static_cast<double>(j)/i;



以上内容整理自《C++primer》《Effective C++》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值