C++ | C++的四种类型转换

  • 时间:
  • 来源:互联网
  • 文章标签:

目录

一.const_cast

二.static_cast

三.reinterpret_cast

四.dynamic_cast


一.const_cast

const_cast类型的转换指的是去掉常量属性的一种类型转换。

例如,在C语言中,我们可以进行以下操作

const int a = 10;

int* p1 = (int*)&a;

而如果在C++中,就可以使用以下语法

const int a = 10;

int* p2 = const_cast<int*>(&a);

这两种方法所生成的指令是一样的,但二者在编译期间的处理方式是有所不同的,例如在C语言中

const int a = 10;

char* p1 = (char*)&a;

//or

double* p1 = (double*)&a;

可以用不同类型的指针指向a,但在C++中不可以

因为const_cast做得只是去除变量的常性,不能做变量类型的转换。 这样做更安全。

同时我们还要注意,const_cast中的类型必须是指针,引用或指向对象类型成员的指针,即不能写为下面这种形式

二.static_cast

static_cast提供编译器认为安全的类型转换,例如在继承中,可以用派生类对象给基类对象赋值。

三.reinterpret_cast

reinterpret_cast类似于C语言中的强制类型转换,例如

int* p = nullptr;

double* b = reinterpret_cast<double*>(p);

缺点就是不够安全。

四.dynamic_cast

dynamic_cast主要用于继承结构中,可以支持RTTI类型识别的上下转换。

例如,有如下一段代码

#include<iostream>
using namespace std;

class Base
{
public:
	virtual void func() = 0;
};

class Derive1 :public Base
{
public:
	void func()
	{
		cout << "call Derive1::func" << endl;
	}
};

class Derive2 :public Base
{
public:
	void func()
	{
		cout << "call Derive2::func" << endl;
	}
};

void show(Base* p)
{
	p->func();
}

int main()
{
	Derive1 d1;
	Derive2 d2;
	show(&d1);
	show(&d2);
}

 运行结果:

现在,我们在Derive2这个类中新增加了一个函数func_2,要求以后当指向Derive2对象的基类指针调用虚函数func()发生动多态时,不再调用func()函数,而调用func_2()函数。 

class Derive2 :public Base
{
	void func()
	{
		cout << "call Derive2::func" << endl;
	}

	void func_2()
	{
		cout << "call Derive2::func_2" << endl;
	}
};

这时我们就可以借用dynamic_cast类型转换,具体代码如下:

#include<iostream>
using namespace std;

class Base
{
public:
	virtual void func() = 0;
};

class Derive1 :public Base
{
public:
	void func()
	{
		cout << "call Derive1::func" << endl;
	}
};

class Derive2 :public Base
{
public:
	void func()
	{
		cout << "call Derive2::func" << endl;
	}

	void func_2()
	{
		cout << "call Derive2::func_2" << endl;
	}
};

void show(Base* p)
{
	Derive2* _p = dynamic_cast<Derive2*>(p);
	/*dynamic_cast会检查p指针指向的是否是一个Derive2类型的对象
	这一过程是系统通过p的vfptr访问vftable,来查看当前vftable中存放的RTTI信息实现的
	如果是,则会返回Derive2对象的地址给_p,
	否则返回nullptr*/

	if (_p != nullptr)
	{
		_p->func_2();
	}
	else
	{
		p->func();
	}
}

int main()
{
	Derive1 d1;
	Derive2 d2;
	show(&d1);
	show(&d2);
}

运行结果:

本文链接http://www.taodudu.cc/news/show-1781965.html