一,C++类型转换
C++丰富的类型允许根据需求选择不同的类型,这也使计算机的操作更加复杂。例如,将两个short值相加涉及到的硬件编码指令可能与将两个long值相加不同。由于有11种整型与3种浮点型,据此计算机要处理大量不同的情况,尤其是对不同的类型进行运算时。为处理这些潜在的混乱,C++自动执行很多类型转换,例如:
1.1,初始化与赋值进行的转换
int a = 20;
long b = a;
将一个值赋给取值范围更大的类型通常不会导致什么问题,然而,将一个很大的值赋给较小范围的类型会降低精度。将浮点类型的值赋给整形变量可能会导致两个问题,首先,将浮点值转换为整形会将数字截短(除掉小数部分)。其次,double值对int来说可能太大。
1.2,表达式中的转换
当同一个表达式包含不同的算术类型时,在这种情况下,C++将自动执行两种转换。首先,一些类型在出现时便会自动转换;其次,有些类型在与其他类型同时出现在表达式中时将被转换。先看自动转换,在计算表达式时,C++将bool、char、short转换为int,这些转换称为整形提升。将不同类型进行算术运算时,也会进行一些转换,例如将int与float相加时。当涉及两种类型时,较小的类型将被转换为较大的类型。
1.3,强制类型转换
C++允许通过强制类型转换机制显示进行类型转换,强制类型转换的格式有两种格式,如下:
(typename) value;
typename (value);
1.4,C风格的类型转换存在的问题
C风格的类型转换格式很简单(TYPE)EXCEPTION,但是C风格的类型转换有不少的缺点。有的时间C风格的转换是不合适的,因为它可以在任意类型之间转换。把一个指向const对象的指针转换成指向non const对象的指针,把一个基类指针转换成派生类指针,这两种转换之间的区别很大,但是传统的C风格的类型转换并没有区分这些。C风格的类型转换的另一个缺点是不容易查找,它是有一个括号加一个标识符组成,这样的东西在C++程序里很多,C++为了克服这些缺点引入四个新的类型转换运算符。
二,C++ 类型转换运算符
2.1,const_cast
作用:将对象的常量性移除,将一个常对象转换成非常的对象。
实例:
class Student{
public:
string name;
public:
Student(string name):name(name){}
};
int main(){
const Student *p = new Student("zhangsan");
Student *pObj = const_cast<Student *>(p); //把一个指向常对象的指针,转换成指向非常对象的指针
pObj->name = "";
}
2.2,static_cast
作用:强迫进行隐式转换。
实例:
- 用于基类和派生类之间的指针或引用的转换,这种转换把派生类的指针或引用转换为基类是安全的。但是,把基类指针或引用转换为派生类时,由于没有进行动态类型检测,所以是不安全的。
- 把void类型的指针转换成目标类型的指针(不安全),需要进行强制类型转换。
- void指针可以指向任意类型的数据,即可用任意数据类型的指针对void指针赋值。
- 用于内置的基本的数据类型之间的转换。
2.3,dynamic_cast
作用:用来执行判断是否可以进行”安全向下类型转型”,即一个基类指针是否可以转换成一个派生类指针。
实例:
Type *q = dynamic_cast<Type *>(p);
q = dynamic_cast<Type *>(p);
当p实际指向的类对象是Type类对象或是Type类的派生类的对象,返回一个Type *,否则返回值为NULL。
int main(){
Base *pBaseObj = new Derived(10, 100); //基类对象指针实际指向的是一个派生类对象
Derived *pDerivedObj = dynamic_cast<Derived*>(pBaseObj);
if(pDerivedObj){
pDerivedObj->test();
} else {
cout<<"std::bad_cast"<<endl;
}
Base *pBase = new Base(10); //基类对象指针指向的是一个基类对象
Derived *pDerived = dynamic_cast<Derived*>(pBase);
if(pDerived){
pDerived->test();
} else {
cout<<"std::bad_cast"<<endl;
}
}
输出结果:
Derived test.
std::bad_cast
Process returned 0 (0x0) execution time : 0.009 s
Press any key to continue.
2.4,reinterpret_cast
作用: interpret是解释的意思,reinterpret即为重新解释,为二进制形式的数据重新解释,但是不改变其值。
实例:扫描二维码关注公众号,回复: 2572762 查看本文章
int main(){
int i;
char *ptr = "hello";
i = reinterpret_cast<int>(ptr);
cout<<i<<endl;
}
输出结果:
4644900
Process returned 0 (0x0) execution time : 0.048 s
Press any key to continue.
2.5,使用C++而不是C风格类型转换的优点
- 类型转换在代码中比较容易识别。
- 各类型转换运算符的功能越单一,编译器越可能诊断出错误应用。例如,想把常量性去掉除非使用新式的const_cast否则无法通过编译。