C++强制类型转换

1、static_cast

用法:

static_cast<type_id(类型说明符)> (expression(变量或者表达式))
例如:
double d = 3.14159265;
int a = static_cast<int> (d);

该运算符把 (type_id - 变量或者表达式) 转换为 <expression - 类型说明符>类型,但是没有运行时类型检查来保证转换的安全性,主要有如下几种用法:

  1. 用于类层次结构中基类(父类)和 派生类 (子类)之间指针或引用的转换。但是需要注意的是:
    进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
    进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的
  2. 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。但是这种安全性需要自己注意。
  3. 把空指针转换成为目标类型的空指针。
  4. 把任何类型的表达式转换成为void类型。

注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
类层次中不能将两个没有联系的类进行转换
在编译期间强制转换

示例:

class A 
{

};
class B :public A
{

};
void Test2()
{
	A* ptra = new A;
	B* ptrb;
	ptrb = static_cast<B*> (ptra);//进行下行转换 将基类指针转换为派生类指针 不安全
	ptra = static_cast<A*> (ptrb);//进行上行转换
}

2、const_cast

用法:

const_cast<type_id> (expression)

主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用。
例如:


const_case<int*> (&num)
去掉const属性,因为不能把一个const变量直接赋给一个非const变量,必须要转换。

示例:

void Test3(const char* s)
{
	ptr[1] = '2';
	cout << s << endl;
}
int main()
{
	char str1[] = "hello";
	Test3(str1);
	return 0;
}

这时肯定会报错:
在这里插入图片描述
当我们使用 const_cast 去除其const 属性后

void Test3(const char* s)
{
	char* ptr = nullptr;
	ptr = const_cast<char*> (s);
	ptr[1] = '2';
	cout << s << endl;
}
int main()
{
	char str1[] = "hello";
	Test3(str1);
	const char* cptr = "hello";
	Test2(cptr);//这样是无法进行去除 const 属性的,因为其本身就是const 属性的
	return 0;
}

在这里插入图片描述
总结 const_cast 的作用:

1、常量指针 被强转为 非常量指针,且仍然指向原来的对象;
2、常量引用 被强转为 非常量引用,且仍然指向原来的对象;
3、常量对象 被强转为 非常量对象。

示例:1、常量指针 被强转为 非常量指针,且仍然指向原来的对象

class A  
{  
public:  
     A()  
     {  
      m_iNum = 0;  
     }  
      
public:  
     int m_iNum;  
};  
      
void foo()  
{  
    //1. 指针指向类  
    const A *pca1 = new A;  
    A *pa2 = const_cast<A*>(pca1);  //常量对象转换为非常量对象  
    pa2->m_iNum = 200;    //fine  
     
    //转换后指针指向原来的对象  
    cout<< pca1->m_iNum <<pa2->m_iNum<<endl; //200 200  
      
    //2. 指针指向基本类型  
    const int ica = 100;  
    int * ia = const_cast<int *>(&ica);  
    *ia = 200;  
    cout<< *ia <<ica<<endl;   //200 100  
}

2、常量引用转为非常量引用

class A
{
public:
  A()
  {
	m_iNum = 1;
  }
 
public:
  int m_iNum;
};
 
void foo()  
{  
 
  A a0;
  const A &a1 = a0;
  A a2 = const_cast<A&>(a1); //常量引用转为非常量引用
	
  a2.m_iNum = 200;    //fine  
 
  cout<< a0.m_iNum << a1.m_iNum << a2.m_iNum << endl; //1 1 200  
}

注意:

const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用
const_cast是不能用来执行任何类型的转换的(const_cast只能调节类型限定符,不能更改基础类型)

3、reinterpret_cast

用法:

reinterpret_cast<type_id> (expression)
不相关类型的转换(相当于C语言中的强转)
  1. 改变指针或引用的类型
  2. 将指针或引用转换为一个足够长度的整形
  3. 将整型转换为指针或引用类型。

示例:

#include<iostream>
int main()
{
	int a = 10;
	int* pa = &a;
	long b = reinterpret_cast<long>(pa);//把一个指针转换为一个整数,取出地址值
	long* pb = reinterpret_cast<long*>(pa);//将 int * 转换为 long *
	return 0;
}

4、dynamic_cast

用法:

dynamic_cast<type_id> (expression) type-id必须是类指针,类引用或者void*
用于将一个父类的指针或引用转化为子类的指针或引用(安全的向下转型)

说明:

  1. 基类指针所指对象是派生类对象,这种转换是安全的;
  2. 基类指针所指对象为基类对象,转换失败,返回结果为0。

示例:

class Base
{
public:
	Base() {};
	virtual void show() { cout << "Base\n"; }
};

class Derive :public  Base
{
public:
	Derive() {};
	virtual void  show() { cout << "Derive\n"; }
};

int main()
{
	Base* base = new Derive;
	if (Derive * ptr1 = dynamic_cast<Derive*>(base))
	{
		cout << "转换成功" << endl;
		ptr1->show();
		cout << endl;
	}

	base = new Base;
	if (Derive * ptr2 = dynamic_cast<Derive*>(base))
	{
		cout << "转换成功" << endl;
		ptr2->show();
		cout << endl;
	}
	else
	{
		cout << "转换失败" << endl;
	}
	
	delete(base);
	return 0;
}

注意:

1.对于类的dynamic_cast转换,基类中一定要有虚函数,否则编译不通过。
2.对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针。
3.对引用进行dynamic_cast,失败抛出一个异常bad_cast,成功返回正常cast后的对象引用。
4.dynamic_cast在运行期强制转换,运行时进行类型检查,较安全。
5.不能用于内置的基本数据类型的强制转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值