标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。在C++中,使用数据类型转换时,该怎样选用合适的数据类型转换方式呢?下面分别对这几种转换方法的使用场景做一个说明:
1) static_cast
使用方法: static_cast < type-id > ( expression )
功能: 任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
把expression转换为type-id类型,无运行时类型检查,转换存在不安全性;
1:void指针->其他类型指针
2:改变通常的标准转换
3:避免出现可能多种转换的歧义
它主要有如下几种用法:
① 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
② 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③ 把void指针转换成目标类型的指针(不安全!!)
④ 把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
2) dynamic_cast
使用方法: dynamic_cast < type-id > ( expression )
说明: 安全的向下转型,从基类到派生类的相关转换。该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void*。
如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
使用场景: dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
注意事项:
① dynamic_cast是动态转换,只有在基类指针转换为子类指针时才有意义。
② dynamic_cast<>需要类成为多态,即包括“虚”函数,并因此而不能成为void*。
③ static_cast和dynamic_cast可以执行指针到指针的转换,或实例本身到实例本身的转换,但不能在实例和指针之间转换。static_cast只能提供编译时的类型安全,而dynamic_cast可以提供运行时类型安全。
3)reinpreter_cast
使用方法: reinpreter_cast< type-id> (expression)
功能: 处理无关类型之间的转换。它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
使用情况:
1.从指针类型到一个足够大的整数类型
2.从整数类型或者枚举类型到指针类型
3.从一个指向函数的指针到另一个不同类型的指向函数的指针
4.从一个指向对象的指针到另一个不同类型的指向对象的指针
5.从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
6.从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针
说明: C++primer指出该转换运算符是为运算对象的位模式提供较低层次上的重新解释,所谓“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式的重新解释。
比如:
int i;
char *p = "This is an example.";
i = reinterpret_cast<int>(p);
此时结果,i与p的值是完全相同的。reinterpret_cast的作用是说将指针p的值以二进制(位模式)的方式被解释为整型,并赋给i,//i 也是指针,整型指针;一个明显的现象是在转换前后没有数位损失。
4) const_cast
用法: const_cast< type_id>(expression)
使用场景: 该运算符用来修改类型的const或volatile属性。除了const或volatile修饰外,type_id和expression的类型是一样的。
const_cast常用于有关函数重载的上下文,见c++primer 209页。
const string& shorterString(const string& s1,const string& s2)
{
return s1.size()<=s2.size()? s1 : s2;
}
该版本调用shorterString的参数是两个const string对象引用,返回const string的引用。如实参为非常量const引用,返回值仍为const string引用。为了得到重载版本的返回值为非常量string的引用,我们引入const_cast。
string& shorterString(string& s1,string& s2)
{
auto &r=shorterString(const_cast<const string&>(s1),const_cast<const string&>(s2));
return const_cast<string&>(r);
}
重载版本首先将实参强制转化为对const的引用,调用函数的const版本,返回const引用,又将其转换为普通的string引用(这是安全合法的,因为这个引用实际上绑定的是某个初始的非常量实参)。
注意事项: 常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。用于强制消除对象的常量性。它是唯一能做到这一点的C++风格的强制转型。
本文详细解析了C++中的四种类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast的使用场景和功能,帮助开发者理解如何在不同情况下选择合适的转换方式。

5295

被折叠的 条评论
为什么被折叠?



