C++ 的强制类型转换

C++ 的强制类型转换

目录(转换方式):

1 、static_cast

2 、dynamic_cast

3、reinterpret_cast

4、const_cast

5、类型转换使用建议

一、 static_cast: 用于基本类型之间的转换

static_cast<>() 可以说是神通广大。

使用方法 : type y = static_cast< type >( expression );

// type-> 需要转换成的目标类型
// expression -> 需要转换的变量或者表达式
//1、基本类型的转化
int age = 100;
double age1=static_cast< double >( age ); //将 int类型转换成 double

//2、父子类之间的转换   class Dog 继承至 class animal
Dog *dog1=new Dog();
Animal *al=static_cast<Animal *>(dog1);  //之类性转换成父类型
Dog *dog1=static_cast<Dog *>(al);   //父类型的指针到子类的指针(父类到子类有风险)

Dog dog2;
Animal &a2=static_cast<Animal &>(dog2); //之类性转换成父类型
Dog &dog2=static_cast<Dog &>(a2);      //父类型的引用到子类的引用(父类到子类有风险)

// 3、把空指针转换成目标类型的空指针
int *p=static_cast<int *>(NULL);
Dog *dog=static_cast<Dog*>(NULL);

// 4、把任何类型的表达式转换成void类型
int *p=new int[19];
void *vp=static_cast<void *>(p);
vp=p;

常见的基本数据类型:

  • 整数类型(int):用于表示整数,包括正整数、负整数和零。

  • 浮点数类型(float和double):用于表示实数,即带有小数点的数。

  • 字符类型(char):用于表示单个字符,可以是字母、数字、符号等。

  • 布尔类型(bool):用于表示真或假、是或否等。

使用时的陷阱:

1、static_cast : 可以用于类的上下转型。但是,这种转换方式没有运行时检查,因此可能会导致安全问题。

2、static_cast不能转换掉表达式的const、volatile或unaligned属性。如果需要改变这些属性,需要考虑其他类型的转换或使用方法。

二、 dynamic_cast 用于类之间的上下转型

dynamic_cast 主要用于实现多态性,通过基类的指针或引用来调用派生类的成员函数。

dynamic_cast ->如果类型转换失败 返回 NULL

说明: nullptrNULL在C++中都用于表示空指针,那么两者有何区别

  • nullptr 是C++11新引入的 ,nullptr的含义更加明确,它专门用于表示空指针,没有其他的含义,更安全。
  • NULL在C++中通常被定义为整型常量,需要隐式地转换为指针类型。

使用方式: type y = dynamic_cast< 目标类型 >( 源指针 )*

#include<iostream>
#include<string>

using namespace std;

class Test {
public:
	//构造函数
	Test(int age = 12, string name = " 吴献丰 ") {
		age_ = age;
		name_ = name;
	}
	virtual void paly() {
		cout << "一起去玩吗?" << endl;
	}
	//析构函数
	~Test()  { }
protected:
	int age_;
	string name_;
};

class Test2 : public Test {
public:
	Test2(string name) {
		name_ = name;
	}
	void paly() {
		cout << "一起去吃汉堡王吗?" << endl;
	}
	Test2() {  }
private:
	string addr_;
};

int main() {
	Test2 *test2 = new Test2( "重庆秀山" );

	// dynamic_cast  ->如果类型转换失败 返回 NULL
	Test *test = dynamic_cast< Test * > ( test2 );

	if (test == NULL) {
		cout << "类型转换失败: " << endl;
	}else {
		test->paly(); //这里调用的是 派生类的 paly方法->输出一起去吃汉堡王吗?
	}

	return 0;
}

无效的转换 : 基类 -》 派生类

//  Test2  继承至 Test 
Test* test = new Test();
Test2 *test2 = new Test2();

Test2 *t = dynamic_cast< Test2 * > ( test );
Test2* t = dynamic_cast<Test2*>(test);
if (t == NULL) {
	cout << "类型转换失败" << endl;  //程序运行后会输出这句话
}

为什么要使用 dynamic_cast :

1、可以使用基类指针来操作不同类型的对象,而无需知道对象的具体类型。

2、实现基类和派生类的安全转换。如果转换成功,我们可以通过基类的指针来访问派生类的方法。

三、reinterpret_cast 常用于不同类型指针之间的强制转换,甚至是将指针转 换成 整数.

使用方式: type y = reinterpret_cast< type >( expression )

// type-> 需要转换成的目标类型
// expression -> 需要转换的变量或者表达式

Demo : 常见的几种用法

1 、指针之间的转换:例如将int指针转换为char指针。

int x = 10;  
int* int_ptr = &x;  
char* char_ptr = reinterpret_cast<char*>(int_ptr);

2、指针与整数之间的转换:可以指针转换为整数类型,或将整数类型转换为指针。

int x = 10;  
int* int_ptr = &x;  
int int_val = reinterpret_cast<int>(int_ptr);

注意:

  • 这种转换方式没有进行类型检查,因此风险较高。
四、const_cast 主要用于去除对象的常量性限制,或者添加常量性限制

将const对象转换成非const对象 进行修改。

使用方式:

type y = const_cast< type >( expression )

举例说明:

int a = 3;  
const int *b = &a;      // b是一个指向常量的指针,不能通过b修改a的值  
int* c = const_cast<int*>(b); // 使用const_cast去除b的const属性,得到指向非常量的指针c  
*c = 4;                // 通过c修改a的值  
cout << a << *c;        // 输出两个4,表明a的值已经被修改

补充: 对于 const的位置,起到的作用

  • const 加在最前面 : const int *age = &a; // age 所指向的地址的内容不能被改变。

  • const 加在后面: int * const age=&a; // age 的值(也就是它所指向的地址)在初始化后不能再被改变。也就是说age只能指向a。

  • const 加在前后 : const int * const age = &a; //age 所指向的地址的内容不能被改变 , 同时 age 只能指向a, 指向其他变量的地址会报错。也就是说 age 的值和它所指向的地址的内容都不能被改变。

注意:

1、const_cast不能用于修改变量本身的const属性,只能修改指针或引用的const属性,再通过间接修改的方式来改变变量的值
在这里插入图片描述


2、常量字符串不能去 const 修改。编译通过了,但是程序运行时之间崩了。

在这里插入图片描述

3、在去常量限定符之间,要保证指针所指向的内存能够修改,不能修改会引起异常。
4、仅针对指针和引用。

类型转换使用总结:

1、static_cast 静态·类型·转换,编译时C++编译器会对类型进行检查,所以能隐射类型转换的,就用static_cast.

2、dynamic_cast<>() 动态类型转换,安全的虚基类和子类之间转换,运行时也会进行类型检查。

3、const_cast<>() 去除变量的只读属性。

4、不同类型之间进行强制类型转换,用reinterpret_cas<>()进行重新解释。

5、static_cast <>()和reinterpret_cas<>(),基本上把c语言中的 强制类型转换给覆盖了。值得注意的是reinterpret_cas<>()很难保证移植性。

C++大牛建议: 一般情况下,不建议进行类型转换,避免进行类型转换。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零二年的冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值