类型转换

1、简介

类型转换的含义是经过改变一个变量的类型为别的类型从而改变该变量的表示方式。程序员

2、C++强制类型转换

C风格的强制转换不安全。express

C++强制类型转换:安全

  • 在C++语言中新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。
  • 新类型的强制转换能够提供更好的控制强制转换过程,容许控制各类不一样种类的强制转换。
  • C++中风格是static_cast (content)。C++风格的强制转换其余的好处是,它们能更清晰的代表它们要干什么。程序员只要扫一眼这样的代码,就能当即知道一个强制转换的目的。

3、具体介绍

一、static_cast:通常的转换,用于数据类型的强制转换,强制将一种数据类型转换为另外一种数据类型。函数

int a = 98;
	char c = static_cast<char>(a);
	cout << c << endl;// b

基础数据类型指针,对象指针不可转换。测试

//基础数据类型指针
	int* p = NULL;
	char* sp = static_cast<char*>(p);//无效

	//对象指针
	Building* building = NULL;
	Animal* ani = static_cast<Animal*>(building);//无效

能够转换具备继承关系的指针或者引用ui

//父类指针转成子类指针
	Animal* ani = NULL;
	Cat* cat = static_cast<Cat*>(ani);
	//子类指针转成父类指针
	Cat* soncat = NULL;
	Animal* anifather = static_cast<Animal*>(soncat);

	//还有具备继承关系的指针或者引用
	Animal aniobj;
	Animal& aniref = aniobj;
	Cat& cat = static_cast<Cat&>(aniref);

	Cat catobj;
	Cat& catref = catobj;
	Animal& anifather2 = static_cast<Animal&>(catref);

二、dynamic_cast<type_id> (expression), 转换具备继承关系的指针或者引用,在转换前会进行对象类型检查,而且
只能由子类型转成基类型极可能失败。指针

  1. 其余三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。code

  2. 不能用于内置的基本数据类型的强制转换对象

    int a = 10;
    char c = dynamic_cast<char>(a);//无效
  3. dynamic_cast转换若是成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。继承

  4. 使用dynamic_cast进行转换的,基类中必定要有虚函数,不然编译不经过。

    B中须要检测有虚函数的缘由:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的状况,此时转换才有意义。这是因为运行时类型检查须要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。

  5. 在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是同样的。在进行下行转换时,dynamic_cast具备类型检查的功能,比static_cast更安全。

    ​ 向上转换,即为子类指针指向父类指针(通常不会出问题),内存大转小;向下转换,即将父类指针转化子类指针,不安全。 向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换之后的对象类型必定要相同,不然转换失败。

    在C++中,编译期的类型转换有可能会在运行时出现错误,特别是涉及到类对象的指针或引用操做时,更容易产生错误。Dynamic_cast操做符则能够在运行期对可能产生问题的类型转换进行测试。

//非继承关系的指针
	Animal* ani = NULL;
	Building* building = dynamic_cast<Building*>(ani);//报错
	//具备继承关系指针
	Animal* ani = NULL;
	Cat* cat = dynamic_cast<Cat*>(ani);//报错  缘由在于 dynamic作类型安全检查

	Cat* cat = NULL;
	Animal* ani = dynamic_cast<Animal*>(cat);

三、 const_cast:const限定符一般被用来限定变量,用于表示该变量的值不能被修改,而const_cast则正是用于强制去掉这种不能被修改的常数特性,但须要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。

  1. 常量指针被强转为很是量指针,且仍然指向原来的对象;
  2. 常量引用被强转为很是量引用,且仍然指向原来的对象;
  3. 常量对象被强转为很是量对象。
//基础数据类型
	int a = 10;
	const int& b = a;	//b = 10;
	int& c = const_cast<int&>(b);
	c = 20;
	cout << "a:" << a << endl;//20
	cout << "b:" << b << endl;//20
	cout << "c:" << c << endl;//20

	const int a = 10;
	const int& pp = a;
	int& cc = const_cast<int&>(pp);
	cc = 100;
	

	//指针   增长或者去除变量的const性
	const int* p = NULL;
	int* p2 = const_cast<int*>(p);

	int* p3 = NULL;
	const int* p4 = const_cast<const int*>(p3);

四、reinterpret_cast 用法:reinterpret_cast<type_id> (expression)

reinterpret_cast主要有三种强制转换用途:

  1. 改变指针或引用的类型、
  2. 将指针或引用转换为一个足够长度的整形、
  3. 将整型转换为指针或引用类型。

type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。

它能够把一个指针转换成一个整数,也能够把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还能够获得原先的指针值)。

在使用reinterpret_cast强制转换过程仅仅只是比特位的拷贝,所以在使用过程当中须要特别谨慎!

//1. 无关的指针类型均可以进行转换
	Building* building = NULL;
	Animal* ani = reinterpret_cast<Animal*>(building);

	//2. 函数指针转换
	FUNC1 func1;
	FUNC2 func2 = reinterpret_cast<FUNC2>(func1);

4、结论

  • 必须清楚地知道转变的变量,转变前是什么类型,转换后是什么类型,以及转换后有什么后果。
  • 通常状况下,不建议使用类型转换,避免进行类型转换。
相关文章
相关标签/搜索