Cpp||类型转换

本文详细介绍了C++中各种类型转换的方式,包括隐式类型转换、强制类型转换以及C++特有的四种命名类型转换操作符:static_cast、reinterpret_cast、const_cast和dynamic_cast。同时,探讨了类型转换的原因和RTTI在C++中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cpp类型转换

1:c语言中的类型转换
1.1:隐式类型转换:意义相似的类型
int main(){
	int a=2;
    float f=1.0;
    char c='a';
    a=f;//隐式类型转换
    c=f;//隐式类型转换
    return 0;
}
  • 缺陷:转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换
1.2: 强制类型转换:意义差距较大的类型
#include<stdio.h>
  int main(){
   int a=20;
   int*p =&a;
 
   printf("*p=%d\n",*p);
    printf("p=%p\n",p);
   printf("&a=%p\n",&a);
 
   float b=10;
   int* pb=(int*)&b; //强制类型转换
   printf("pb=%p\n",pb);
   printf("&b=%p\n",&b);                                   
   printf("*pb=%d\n",*pb); 
   return 0;
 }

2:C++中的类型转换
  • 标准C++为了加强类型转换的可能性,引入了以下四种命名的强制类型转换操作符
  • static_cast
  • reinterpret_cast
  • const_cast
  • dynamic_cast
2.1:static_cast
int main()
{
double d = 12.34;
int a = static_cast<int>(d);
cout<<a<<endl;
return0;
}

static_cast:所有支持隐式类型转换的都可以用
int* pa=&a;
pa=static_case<int*>a;//不支持,风险较大

2.2:reinterpret_cast
  • 支持强制类型转换

  • reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型

int main(){
    int a=10;
    int *pa=&a;
    pa=reinterpret_cast<int*> (a);
    //强制类型转换
	return 0;
}
2.3:const_cast
  • const_cast最常用的用途就是删除变量的const属性,方便赋值
int main(){
	const int a=10;
    int *pa=const_cast<int*> (&a);
    int &ra=const_cast<int&> (a);
    ra=15;
    *pa=20;
    return 0;
}
2.4:dynamic_cast
  • dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)
  • 向上转型:子类对象指针->父类指针/引用(不需要转换,赋值兼容规则) 向下转型:父类对象指针->子类指针/引用(用dynamic_cast转型是安全的)

【注意】:

  • 1.dynamic_cast只能用于含有虚函数的类
  • 2.dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
  • 3.要转换的类型必须要实现多态
class A{
public:
    virtual void fun(){
        cout<<"A::fun()"<<endl;
    }
private:
    int _a;
};
class B:public A
{
public:
	virtual void fun(){
		cout<<"B::fun()"<<endl;
	}
private:
	int _b;
}

int main(){ 
    A a;
    B b;
	a=b;
	//b=a;//子类变量不能赋值给父类
	//B* b=&a; //父类地址不能赋值给子类指针
	A*pa = &b;
	A& ra=b;
	//不安全
	B& rb=(B&) a;
	//父类指针/引用赋值给子类指针/引用:可以强制类型转换,但是不一定安全
	B* pb =(B*) &a;
	//安全
	B *pb2=(B*)pa;
	//静态转换不会检查转换对象是否安全
	B* pbs=static_cast<B*> (&a);
	//动态转换会检查转换类型是否安全:
	//如果不安全返回NULL
	//如果安全,返回正确地址
	B* pbs2=dynamic_cast<B*> (&a);
	//实现多态的情况下才能使用dynamic_cast来强制类型转换
	B*pbd2=dynamic_cast<B*> (pa);
    return 0;
}
3:explict
  • 关键字explict阻止经过转换构造函数进行的隐式转换的发生
class A
 {
public :
 explicit A (int a)
 {
 cout<<"A(int a)" <<endl;
 }
 A(const A& a)
 {
 cout<<"A(const A& a)" <<endl;
 }
private :
 int _a ;
 };
int main ()
 {
 A a1 (1);
 // 隐式转换-> A tmp(1); A a2(tmp);
 A a2 = 1;
 }
4.Cpp需要类型转换的原因
  • C风格的转换式很简单,但是有很多缺点
  • 1.隐式类型转换有些情况下可能出现问题
  • 2.显示类型转换将所有情况混合在一起,代码逻辑不清晰
    【小结】

父类指针/引用赋值给子类指针/引用:强制类型转换,但是不一定安全

5.RTTI
  • RTTI:Run-time Type indentification的简称,既:运行时类别识别
  • c++通过以下网是来支持RTTI
  • 1.typeid运算符
  • 2.dynamic_cast运算符
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值