C++强制类型转换

C++强制类型转换,第1张

C++强制类型转换 1、static_cast

用法:

static_cast (expression(变量或者表达式))
例如:
double d = 3.14159265;
int a = static_cast (d);

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

  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 (ptra);//进行下行转换 将基类指针转换为派生类指针 不安全
	ptra = static_cast (ptrb);//进行上行转换
}
2、const_cast

用法:

const_cast (expression)

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

const_case (&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 (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(pca1);  //常量对象转换为非常量对象  
    pa2->m_iNum = 200;    //fine  
     
    //转换后指针指向原来的对象  
    cout<< pca1->m_iNum <m_iNum<(&ica);  
    *ia = 200;  
    cout<< *ia < 

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

class A
{
public:
  A()
  {
	m_iNum = 1;
  }
 
public:
  int m_iNum;
};
 
void foo()  
{  
 
  A a0;
  const A &a1 = a0;
  A a2 = const_cast(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 (expression)
不相关类型的转换(相当于C语言中的强转)
  1. 改变指针或引用的类型
  2. 将指针或引用转换为一个足够长度的整形
  3. 将整型转换为指针或引用类型。

示例:

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

4、dynamic_cast

用法:

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

说明:

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

示例:

class base
{
public:
	base() {};
	virtual void show() { cout << "basen"; }
};

class Derive :public  base
{
public:
	Derive() {};
	virtual void  show() { cout << "Deriven"; }
};

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

	base = new base;
	if (Derive * ptr2 = dynamic_cast(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.不能用于内置的基本数据类型的强制转换。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/4751391.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-08
下一篇 2022-11-08

发表评论

登录后才能评论

评论列表(0条)

保存