C++中的类型转换

1.static_cast

C语言中所有的隐式类型转换,都可以使用static_cast进行来完成。

int a = 10;
char ch = static_cast<char>(a);

2.reinterpret_cast

reinterpret_cast可以对变量进行重新解释,像一个指针的编号可以解释为一个整型。

int a = 10;
int* pa = &a;
a = reinterpret_cast<int>(pa);
cout << "reinterpret_cast: " <<  a << endl;

此时cout打印的是一个内存编号(整型):

3.const_cast

const定义的常变量是不能进行重新赋值的,但是如果我们使用const_cast让一个指针指向一个const变量所在的空间,就可以通过指针来修改;对应的是C语言的强制类型转换。

const int a = 10;
int* pa = const_cast<int*>(&a);
*pa = 20;
cout << a << endl; //10
cout << *pa << endl;//20

pa中存储的是a的地址,*pa和a打印出来的值理论上来说是一样的,那为什么打印的值不一样?

解答:const修饰的常变量,编译器会做出一些优化,如直接放在寄存器中,或者是定义成一个宏;在流插入时a不会去内存中去取,而是直接找到寄存器或者宏,所以打印的还是10;而*pa会去内存中找,所以打印的是20。

4.dynamic_cast

父类指针或引用可以指向子类的指针或引用,但是如果直接使用子类指针或引用指向父类的指针或引用就会报错。

注意:父类对象是无论如何都无法转换成子类对象的。

class A
{
public:
	virtual void f() {}
};
class B : public A
{};

int main()
{
    A aa;
	B bb;
	bb = aa;
	bb = (B)aa;
	bb = dynamic_cast<B>(aa);
    return 0;
}

这三种写法都是错误的:

dynamic_cast的使用时是条件的:继承关系,父类必须有虚函数,向下转型。

class A
{
public:
	virtual void f(){}
public:
	int _a = 0;
};

class B : public A
{
public:
	int _b = 1;
};

// A*指针pa有可能指向父类,有可能指向子类
void fun(A* pa)
{
	// 如果pa是指向子类,那么可以转换,转换表达式返回正确的地址
	// 如果pa是指向父类,那么不能转换,转换表达式返回nullptr
	B* pb = dynamic_cast<B*>(pa); // 安全的
	//B* pb = (B*)pa;             // 不安全
	if (pb)
	{
		cout << "转换成功" << endl;
		pb->_a++;
		pb->_b++;
		cout << pb->_a << ":" << pb->_b << endl;
	}
	else
	{
		cout << "转换失败" << endl;
		pa->_a++;
		cout << pa->_a << endl;
	}
}

int main()
{
	A aa;
	B bb;
	fun(&aa);
	fun(&bb);
	return 0;
}

使用强制类型转换和dynamic_cast进行转换的区别:

强制类型转换不会做表达式返回检查,类型能够转换成功,但是访问时可能访问到非法地址,如给fun函数传递的是父类的指针,强制将父类指针转化为子类去访问成员变量_b就是非法访问;使用dynamic_cast进行父类转子类时,会进行类型检查,如果是父类指针,会返回nullptr,如果是子类指针,就可以进行转换。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

new出新对象

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

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

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

打赏作者

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

抵扣说明:

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

余额充值