10. 强制类型转换
10.1. static_cast<type> (expr)
1. static_cast
作用和 C 语言风格强制转换的效果基本一样,由于没有运行时类型检查来保证转换的安全性,所以这类型的强制转换和 C 语言风格的强制转换都有安全隐患。
2. 用于基本数据类型之间的转换,如把 int
转换成 char
,把 int
转换成 enum
。这种转换的安全性需要开发者来维护。
3. C++ 的任何的隐式转换都是使用 static_cast
来实现。
4. 基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用 dynamic_cast
)
5. 把空指针转换成目标类型的空指针。
6. 把任何类型的表达式转换成 void
类型。
10.2. dynamic_cast<type> (expr)
type 可以是指针、引用、右值引用。
有条件转换,动态类型转换,运行时类型安全检查(对于指针,转换失败返回 NULL
;对于引用,抛出 std:bad_cast
异常)。
1. 安全的基类和子类之间转换。
2. 必须要有虚函数;必须是公有继承(public)。
3. 相同基类不同子类之间的交叉转换,结果是 NULL
或抛出 std:bad_cast
异常。
1// dynamic_cast
2#include <iostream>
3#include <exception>
4using namespace std;
5
6class Base { virtual void dummy() {} };
7class Derived: public Base { int a; };
8
9int main ()
10{
11 try
12 {
13 Base* pba = new Derived;
14 Base* pbb = new Base;
15 Derived* pd;
16
17 pd = dynamic_cast<Derived*>(pba);
18 if (pd == 0) cout << "Null pointer on first type-cast.\n";
19
20 pd = dynamic_cast<Derived*>(pbb);
21 if (pd == 0) cout << "Null pointer on second type-cast.\n";
22
23 } catch (exception& e) {cout << "Exception: " << e.what();}
24 return 0;
25}
26
27// 输出结果:Null pointer on second type-cast.
10.3. const_cast<type> (expr)
1. 去掉类型的 const
、 volitale
属性(对象本身的属性没有改变);
2. 常量指针被转化成非常量的指针,并且仍然指向原来的对象;
3. 常量引用被转换成非常量的引用,并且仍然指向原来的对象;
4. const_cast
一般用于修改指针。如 const char* p
形式。
如果有一个函数,它的形参是 non-const 类型变量,而且函数不会对实参的值进行改动,这时我们可以使用类型为 const
的变量来调用函数,此时 const_cast 就派上用场了。
1// const_cast
2#include <iostream>
3using namespace std;
4
5void print (char* str)
6{
7 cout << str << '\n';
8}
9
10int main ()
11{
12 const char* c = "sample text";
13 print ( const_cast<char *> (c) );
14 return 0;
15}
16
17// 输出结果:sample text
10.4. reinterpret_cast<type> (expr)
1. reinterpret_cast
是从底层对数据进行重新解释,依赖具体的平台,可移植性差。
2. reinterpret_cast
可以将整型转换为指针,也可以把指针转换为数组。
3. reinterpret_cast
可以在指针和引用里进行肆无忌惮的转换。
10.5. 使用stringstream转换类型
#include <sstream>
sstream 头文件定义了三个类型来支持内存IO:istringstream,ostringstream,stringstream。这些类型可以向 string 写入数据,或从 string 读取数据。
stringstream 的一些操作:
stringstream strm
:strm 是一个未绑定的 stringstream 对象
stringstream strm(s)
:strm 是一个 stringstream 对象,保存字符串 s 的一个拷贝
s = strm.str()
:返回 strm 保存的内容的拷贝
strm.str(s)
:把 strm 保存的内容修改为 s,丢弃之前的内容。
强制类型转换
1#include <iostream>
2#include <sstream>
3using namespace std;
4
5template <class output_type, class input_type>
6output_type Convert(const input_type &input)
7{
8 stringstream strm;
9 strm << input;
10 output_type result;
11 strm >> result;
12 strm.clear();
13 return result;
14}
15
16
17int main(int argc, char ** argv)
18{
19 string strNum = "-22.22";
20 float f = Convert<float>(strNum);
21 cout << f << endl; // -22.22
22
23 float n = 22.22;
24 string str = Convert<string>(n);
25 cout << str << endl; // 22.22
26
27 return 0;
28}
Note
strm调用 成对的 <<
和 >>
之后,状态为 end-of-file
,必须进行 clear
才能进行下一次 <<
操作。
strm.clear()
重置了strm的状态标识,并没有清空数据。如果没有调用 <<
之后没有使用 >>
,可以使用 strm.str("")
清空数据。
10.6. 参考资料
C++中四种强制类型转换区别详解
c++ 四种强制类型转换介绍
C++中使用stringstream简化类型转换
c++ reference
C++强制类型转换操作符 const_cast