首页 > 编程知识 正文

强制类型转换符,c强制类型转换地址

时间:2023-05-06 08:58:41 阅读:220540 作者:3380

C/C++中的类型转换分为两种:隐式类型转换和显式类型转换。

而对于隐式类型转换,在很多时候,不经意间就发生了,比如int类型和float类型赋值时,int类型就会被隐式的转换位float类型。

举例:

int i = 5;float d = i;//隐式类型的转换int* p = (int*)i;//C style,强制类型的转换.

C++对C兼容,所以上述方式的类型转换是可以的,但是有时候会有问题,所以推荐使用C++中的四个强制类型转换的关键字:
static_cast、reinterpret_cast、const_cast 和 dynamic_cast。下面将逐一介绍。

static_cast

这应该四种中是最常见的。用法为:

static_cast < new_type > ( expression )

该运算符把 expression 转换为new_type 类型。

特点:

1、 用于非多态类型的转换
2、 不执行运行时类型检查(转换安全性不如 dynamic_cast)
3、通常用于转换数值数据类型(如 float -> int)
4、 可以在整个类层次结构中移动指针,子类转化为父类安全(向上转换),父类转化为子类不安全(因为子类可能有不在父类的字段或方法)

通常用于转换数值数据类型(如 float -> int):

#include <iostream>using namespace std;int main(int argc, char const *argv[]){float f = 4.5;int a = f; //C-styleint b = static_cast<int>(f);cout << b << endl;return 0;}

编译输出:


现在让我们对代码做一些修改:

#include <iostream>using namespace std;int main(int argc, char const *argv[]){int a = 10;char c = 'a';int* q = (int*) &c;int *p = static_cast<int *>(&c);//编译错误,static_cast 不能将字符转换成指针return 0;}

编译:

这意味着,即使您认为可以将特定对象类型转换为另一个对象,但这是非法的,static_cast也不允许这样做。

static_cast 用于基本数据类型之间的转换,如把int转换成char,把int转换成float。在c++ primer 中说道:c++ 的任何的隐式转换都是使用 static_cast 来实现。

让我们以继承为例,来看看这个例子:

#include <iostream>using namespace std;class Base { }; class Derived : public Base { }; int main(int argc, char const *argv[]){ Derived d1; Base* b1 = (Base*)(&d1); // 允许 Base* b2 = static_cast<Base*>(&d1); return 0;}

编译:
编译,上面的代码将不会出现任何错误。
1、我们取&d1,显式的存入Base中,存储在b1中。
2、我们取&d1,用static_cast将其转换成Base,存储在b2中。

我们知道static_cast执行严格的类型检查,让我们稍微修改一下代码看看,把继承改为private。

#include <iostream>using namespace std;class Base { }; class Derived : private Base { }; int main(int argc, char const *argv[]){ Derived d1; Base* b1 = (Base*)(&d1); // 允许 Base* b2 = static_cast<Base*>(&d1); return 0;}

编译:
即使继承为受保护的,上面的代码也不会编译。因此,要使用static_cast,请将其继承为public。

使用static_cast将“向空指针”和“从空指针”进行强制转换。例子:

#include <iostream>using namespace std;int main(int argc, char const *argv[]){ int i = 10; void* v = static_cast<void*>(&i); int* ip = static_cast<int*>(v); return 0;}

编译:

const_cast

用于删除 const、volatile 和 __unaligned 特性(如将 const int 类型转换为 int 类型 )

const_cast可用于更改const成员函数内的非const类成员。考虑以下代码片段。

#include <iostream>using namespace std;class student { private: int roll; public: // 构造函数 student(int r):roll(r) {} // 在const_cast的帮助下改变roll的const函数 void fun() const { ( const_cast <student*> (this) )->roll = 5; } int getRoll() { return roll; } }; int main(int argc, char const *argv[]){ student s(3); cout << "Old roll number: " << s.getRoll() << endl; s.fun(); cout << "New roll number: " << s.getRoll() << endl; return 0;}

编译输出:

在const成员函数fun()中,编译器将“ this”视为“ const student * const this”,即“ this”是指向常量对象的常量指针,因此编译器不允许通过以下方式更改数据成员“这个”指针。const_cast将“ this”指针的类型更改为“ student * const this”。

const_cast可用于将const数据传递给不接收const的函数。例如:

#include <iostream>using namespace std;int fun(int* ptr) { return (*ptr + 10); } int main(int argc, char const *argv[]){ const int val = 10; const int *ptr = &val; int *ptr1 = const_cast <int *>(ptr); cout << fun(ptr1)<<endl; return 0;}

编译输出:

const_cast比简单类型转换更安全。从某种意义上讲,如果强制类型与原始对象不相同,则强制强制转换不会发生,这是比较安全的。例如:

#include <iostream>using namespace std;int main(int argc, char const *argv[]){ int a1 = 40; const int* b1 = &a1; char* c1 = const_cast <char *> (b1); // 编译程序时出错 *c1 = 'A'; return 0;}

编译:

程序编译失败,因为将“ int *”类型转换为“ char *”

const_cast也可以用来抛弃volatile属性。例如:

#include <iostream>#include <typeinfo> // typeidusing namespace std;int main(int argc, char const *argv[]){ int a1 = 40; const volatile int* b1 = &a1; cout << "typeid of b1 " << typeid(b1).name() << 'n'; int* c1 = const_cast <int *> (b1); cout << "typeid of c1 " << typeid(c1).name() << 'n'; return 0;}

编译输出:
在程序中,b1的typeid是PVKi(指向易失性和整数的指针),而c1的typeid是Pi(指向整数的指针)。

reinterpret_cast

reinterpret_cast是C ++中使用的一种强制转换运算符。

它用于转换任何类型的另一个指针的一个指针,而不管该类是否相互关联。
它不检查指针类型和指针所指向的数据是否相同。

用法如下:

reinterpret_cast <数据类型*>(指针变量);

来看看 reinterpret_cast 简单用法:

#include <iostream>using namespace std;int main(int argc, char const *argv[]){ int* p = new int(65); char* ch = reinterpret_cast<char*>(p); cout << *p << endl; cout << *ch << endl; cout << p << endl; cout << ch << endl; return 0;}


使用reinterpret_cast的目的:

1、reinterpret_cast是一种非常特殊且危险的类型转换操作符。并且建议使用适当的数据类型使用它,即(指针数据类型应与原始数据类型相同)。

2、它可以将任何指针类型转换为任何其他数据类型。

3、当我们要使用位时使用它。

4、它仅用于将任何指针转换为原始类型。

5、布尔值将转换为整数值,即0表示false,1表示true。

来看看下面一个例子:

#include <iostream>using namespace std;// 创建结构体mystructstruct mystruct { int x; int y; char c; bool b; }; int main(int argc, char const *argv[]){ mystruct s; // 结构体赋值 s.x = 5; s.y = 10; s.c = 'a'; s.b = true; // 在强制转换期间,数据类型必须与原始数据类型相同 // 将's'指针转换为'p'中int类型的指针。 int* p = reinterpret_cast<int*>(&s); cout << sizeof(s) << endl; // 打印当前由*p指向的值 cout << *p << endl; // 将指针增加1 p++; // 打印下一个整数值 cout << *p << endl; p++; // 用char *ch将char *指向p。 // char* ch = reinterpret_cast<char*>(p); // 打印(*ch)指定的字符值 cout << *ch << endl; ch++; bool* n = reinterpret_cast<bool*>(ch); cout << *n << endl; cout << *(reinterpret_cast<bool*>(ch)); return 0;}

编译输出:


再看一个例子:

#include <iostream>using namespace std;class A { public: void fun_a() { cout << " In class An"; } }; class B { public: void fun_b() { cout << " In class Bn"; } }; int main(int argc, char const *argv[]){ // 创建B类的对象 B* x = new B(); // 将指向B类引用的对象的指针转换为A类 A* new_a = reinterpret_cast<A*>(x); // 访问A类的函数。 new_a->fun_a(); return 0; }

编译输出:


dynamic_cast

dynamic_cast的转换格式:

dynamic_cast <type-id> (expression)

将expression转换为type-id类型,type-id必须是类的指针、类的引用或者是void *;如果type-id是指针类型,那么expression也必须是一个指针;如果type-id是一个引用,那么expression也必须是一个引用。

最简单的上行转换,比如Derived 继承自Basic,Derived 转换为Basic,进行上行转换时,是安全的,如下:

#include <iostream>using namespace std; class Basic{ public: virtual int test(){return 0;} // 必须为多态以使用运行时检查的 dynamic_cast}; class Derived : public Basic{ public: int test(){return 1;}}; int main(int argc, char const *argv[]){ Basic cBasic; Derived cDerived; Basic * pB1 = new Basic; Basic * pB2 = new Derived; //动态强制转换失败,因此pD1为空。 Derived * pD1 = dynamic_cast<Derived * > (pB1); //动态强制转换成功,因此rD2引用派生对象。 Derived & rD2 = dynamic_cast<Derived &> (*pB2); return 0;}

编译:


参考:static_cast in C++ | Type Casting operators
reinterpret_cast in C++ | Type Casting operators
const_cast in C++ | Type Casting operators

(微信公众号【程序猿编码】)


(添加本人微信号,备注加群,进入程序猿编码交流群,领取学习资料,获取每日干货)

微信公众号【程序猿编码】,这里Linux c/c++ 、Python、Go语言、数据结构与算法、网络编程相关知识,常用的程序员工具。还有汇聚精炼每日时政、民生、文化、娱乐新闻简报,即刻知晓天下事!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。