C++——强制类型转换

强制类型转换是不安全的,因此我们应该尽量避免使用强制类型转换

静态类型转换:
static_cast:
用于低风险转换,如整形、浮点型、字符型之间的相互转换。
例:
#include
using namespace std;
class Static_Cast
{
public: //重载 运算符()
operator int () { return 1; }
operator char*() { return nullptr; }
};
int main()
{
Static_Cast st;
int n=0;
const char * p = “New Dragon Inn”;
n=3.14;
n = static_cast (3.14); // n 的值变为 3
n = static_cast (st); //调用 a.operator int,n 的值变为 1
p = static_cast <char*> (st); //调用 a.operator char*,p 的值变为 NULL
n = static_cast §; //编译错误,static_cast不能将指针转换成整型
p = static_cast <char*> (n); //编译错误,static_cast 不能将整型转换成指针
return 0;
}

reinterpret_cast:
多用于指针、引用之间的转换,因此很不安全
例:
#include
using namespace std;
class Reinterpret_cast
{
public:
int i;
int j;
Reinterpret_cast(int n):i(n),j(n) { }
};
int main()
{
reinterpret_cast re(100);
int &r = reinterpret_cast<int&>(re); //强行让 r 引用 a
r = 200; //把 a.i 变成了 200
cout << re.i << “,” << re.j << endl; // 输出 200,100
int n = 300;
Reinterpret_cast pa = reinterpret_cast<Reinterpret_cast> ( & n); //强行让 pa 指向 n
pa->i = 400; // n 变成 400
pa->j = 500; //此条语句不安全,很可能导致程序崩溃
cout << n << endl; // 输出 400
long long la = 0x12345678abcdLL;
pa = reinterpret_cast<Reinterpret_cast*>(la); //la太长,只取低32位0x5678abcd拷贝给pa
unsigned int u = reinterpret_cast(pa);//pa逐个比特拷贝到u
cout << hex << u << endl; //输出 5678abcd
typedef void (* PF1) (int);
typedef int (* PF2) (int,char *);
PF1 pf1; PF2 pf2;
pf2 = reinterpret_cast(pf1); //两个不同类型的函数指针之间可以互相转换
}

const_cast:
它是四个强制类型转换运算符中唯一能够去除 const 属性的运算符
例:
const string s = “Inception”;
string& p = const_cast <string&> (s);
string* ps = const_cast <string*> (&s); // &s 的类型是 const string*

只能用于const指针和const引用

例:
int num=10;
int & newNum=num;
const int &NewNum=const_cast<const int &>(newNum);
或者:
int * p=(&)num;
const int *newP=const_cast<const int *>

动态类型转换:
dynamic_cast:

多态:将基类(包含虚函数的基类)的指针强制转换为派生类的指针,但是这种转换不检查安全性,即不检查转换后的指针是否确实指向一个派生类对象。
dynamic_cast专门用于将多态基类的指针或引用强制转换为派生类的指针或引用,而且能够检查转换的安全性。对于不安全的指针转换,转换结果返回 NULL 指针

dynamic 非常严格,不允许失去精度,因此不适合于基础类型的强制类型转换。
它仅用于,多态时父类转子类。
例:

//没有多态的情况下
class Base{};
class Child:public Base{};
void test08()
{
Base* base=new Base();
Child * child1=new Child();
Base * baseTest=new Child();
//向上转型测试:Base 对象转 Child 实例 。安全
Base * base1=dynamic_cast<Base *>(child1);
//向下转型测试 :Child 对象转 Base实例 。不安全
Child * child2=dynamic_cast<Child *>(baseTest);//报错,因为没有发生多态
}

//在发生多态的情况下
class Base
{
virtual void func(){}
};
class Child:public Base
{
void func(){}
};
void test08()
{
Base* base=new Base();
Child * child1=new Child();
Base * baseTest=new Child();
//向上转型测试:Base 对象转 Child 实例 。安全
Base * base1=dynamic_cast<Base *>(child1);
//向下转型测试 :Child 对象转 Base实例 。不安全
Child * child2=dynamic_cast<Child *>(baseTest);
//不会报错,因为发生了多态
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值