做内销的网站推荐,一站式做网站平台,网页设计与网站建设毕业设计,ui网站建设C 将类型名作为强制类型转换运算符。
C 引入了四种功能不同的强制类型转换运算符以进行强制类型转换#xff1a;static_cast、reinterpret_cast、const_cast 和 dynamic_cast。
强制类型转换是有一定风险的#xff0c;有的转换并不一定安全#xff0c;如把整型数值转换成指…C 将类型名作为强制类型转换运算符。
C 引入了四种功能不同的强制类型转换运算符以进行强制类型转换static_cast、reinterpret_cast、const_cast 和 dynamic_cast。
强制类型转换是有一定风险的有的转换并不一定安全如把整型数值转换成指针把基类指针转换成派生类指针把一种函数指针转换成另一种函数指针把常量指针转换成非常量指针等。C 引入新的强制类型转换机制主要是为了克服C语言强制类型转换的以下三个缺点。
1 没有从形式上体现转换功能和风险的不同。
例如将 int 强制转换成 double 是没有风险的而将常量指针转换成非常量指针将基类指针转换成派生类指针都是高风险的而且后两者带来的风险不同即可能引发不同种类的错误C语言的强制类型转换形式对这些不同并不加以区分。
2 将多态基类指针转换成派生类指针时不检查安全性即无法判断转换后的指针是否确实指向一个派生类对象。
3 难以在程序中寻找到底什么地方进行了强制类型转换。
强制类型转换是引发程序运行时错误的一个原因因此在程序出错时可能就会想到是不是有哪些强制类型转换出了问题。
使用 C 的方式只需要查找_cast字符串就可以了。甚至可以根据错误的类型有针对性地专门查找某一种强制类型转换。例如怀疑一个错误可能是由于使用了 reinterpret_cast 导致的就可以只查找reinterpret_cast字符串。
C 强制类型转换运算符的用法如下
强制类型转换运算符 要转换到的类型 (待转换的表达式)例如
double d static_cast double (3*5); //将 3*5 的值转换成实数下面分别介绍四种强制类型转换运算符。
static_cast
static_cast 用于进行比较“自然”和低风险的转换如整型和浮点型、字符型之间的互相转换。另外如果对象所属的类重载了强制类型转换运算符 T如 T 是 int、int* 或其他类型名则 static_cast 也能用来进行对象到 T 类型的转换。
static_cast 不能用于在不同类型的指针之间互相转换也不能用于整型和指针之间的互相转换当然也不能用于不同类型的引用之间的转换。因为这些属于风险比较高的转换。
static_cast 用法示例如下
#include iostream
using namespace std;
class A
{
public:operator int() { return 1; }operator char*() { return NULL; }
};
int main()
{A a;int n;char* p New Dragon Inn;n static_cast int (3.14); // n 的值变为 3n static_cast int (a); //调用 a.operator intn 的值变为 1p static_cast char* (a); //调用 a.operator char*p 的值变为 NULLn static_cast int (p); //编译错误static_cast不能将指针转换成整型p static_cast char* (n); //编译错误static_cast 不能将整型转换成指针return 0;
}reinterpret_cast
reinterpret_cast 用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时执行的是逐个比特复制的操作。
这种转换提供了很强的灵活性但转换的安全性只能由程序员的细心来保证了。例如程序员执意要把一个 int* 指针、函数指针或其他类型的指针转换成 string* 类型的指针也是可以的至于以后用转换后的指针调用 string 类的成员函数引发错误程序员也只能自行承担查找错误的烦琐工作C 标准不允许将函数指针转换成对象指针但有些编译器如 Visual Studio 2010则支持这种转换。
reinterpret_cast 用法示例如下
#include iostream
using namespace std;
class A
{
public:int i;int j;A(int n):i(n),j(n) { }
};
int main()
{A a(100);int r reinterpret_castint(a); //强行让 r 引用 ar 200; //把 a.i 变成了 200cout a.i , a.j endl; // 输出 200,100int n 300;A *pa reinterpret_castA* ( n); //强行让 pa 指向 npa-i 400; // n 变成 400pa-j 500; //此条语句不安全很可能导致程序崩溃cout n endl; // 输出 400long long la 0x12345678abcdLL;pa reinterpret_castA*(la); //la太长只取低32位0x5678abcd拷贝给paunsigned int u reinterpret_castunsigned int(pa);//pa逐个比特拷贝到ucout hex u endl; //输出 5678abcdtypedef void (* PF1) (int);typedef int (* PF2) (int,char *);PF1 pf1; PF2 pf2;pf2 reinterpret_castPF2(pf1); //两个不同类型的函数指针之间可以互相转换
}程序的输出结果是
200, 100
400
5678abed上面程序中的各种转换都没有实际意义只是为了演示 reinteipret_cast 的用法而已。在编写黑客程序、病毒或反病毒程序时也许会用到这样怪异的转换。
reinterpret_cast体现了 C 语言的设计思想用户可以做任何操作但要为自己的行为负责。
const_cast
const_cast 运算符仅用于进行去除 const 属性的转换它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。
将 const 引用转换为同类型的非 const 引用将 const 指针转换为同类型的非 const 指针时可以使用 const_cast 运算符。例如
const string s Inception;
string p const_cast string (s);
string* ps const_cast string* (s); // s 的类型是 const string*dynamic_cast
用 reinterpret_cast 可以将多态基类包含虚函数的基类的指针强制转换为派生类的指针但是这种转换不检查安全性即不检查转换后的指针是否确实指向一个派生类对象。dynamic_cast专门用于将多态基类的指针或引用强制转换为派生类的指针或引用而且能够检查转换的安全性。对于不安全的指针转换转换结果返回 NULL 指针。
dynamic_cast 是通过“运行时类型检查”来保证安全性的。dynamic_cast 不能用于将非多态基类的指针或引用强制转换为派生类的指针或引用——这种转换没法保证安全性只好用 reinterpret_cast 来完成。
dynamic_cast 示例程序如下
#include iostream
#include string
using namespace std;
class Base
{ //有虚函数因此是多态基类
public:virtual ~Base() {}
};
class Derived : public Base { };
int main()
{Base b;Derived d;Derived* pd;pd reinterpret_cast Derived* (b);if (pd NULL)//此处pd不会为 NULL。reinterpret_cast不检查安全性总是进行转换cout unsafe reinterpret_cast endl; //不会执行pd dynamic_cast Derived* (b);if (pd NULL) //结果会是NULL因为 b 不指向派生类对象此转换不安全cout unsafe dynamic_cast1 endl; //会执行pd dynamic_cast Derived* (d); //安全的转换if (pd NULL) //此处 pd 不会为 NULLcout unsafe dynamic_cast2 endl; //不会执行return 0;
}程序的输出结果是
unsafe dynamic_cast1如果上面的程序中出现了下面的语句
Derived r dynamic_cast Derived (b);那该如何判断该转换是否安全呢不存在空引用因此不能通过返回值来判断转换是否安全。C 的解决办法是dynamic_cast 在进行引用的强制转换时如果发现转换不安全就会拋出一个异常通过处理异常就能发现不安全的转换。