C++--类型转换--1128

1.C语言中的类型转换

分为隐式类型转化、显示强制类型转化。

隐式类型转化用于意义相近的类型,比如int,double,short都是表示数值的类型

 int i=1; double d=i;  //编译、结果无问题  这里是隐式类型转换。

显示强制类型转换

显示强制类型用于意义不相近的类型,比如地址和int

int *p=&i;  int address=(int) p;//使用显示强制类型转换时编译、结果才无问题。

 缺陷:转换的可视性差,所有类型转换的形式都是一种相同形式,错误难以排查。

2.C++的类型转换

标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符。

static_cast          reinterpret_cast        const_cast         dynamic_cast

2.1 static_cast

static_cast 用于非多态类型的转换(静态转换)。编译器隐式执行的任何类型转换都可以用static_cast(用于意义相近的类型,不相关的类型用会报错)

int main()
{
    double d=23.14;
    int a=static_cast<int>(d);
    cout<<a<<endl;
    return 0;
}

2.2 reinterpret_cast

不相关类型的转换

int main()
{
	double d = 23.14;
	int a = static_cast<int>(d);
	int* p = reinterpret_cast<int*>(a);//将一个表示数值的整形变成了地址
	return 0;
}

2.3 const_cast

删除变量的const属性,方便赋值。

int main()
{
	const int a = 2;
	int* p = const_cast<int*>(&a);//const int* 转换成了int*
	*p = 3;
	cout << a << endl << *p << endl;
	return 0;
}

 为什么我们在监视窗口确实看到了a的值被修改成了3,而最终结果仍然是2呢?

这里是编译器的一些优化,有些编译器会将const变量直接放在寄存器中,需要使用a的时候直接从寄存器拿,而调试相当于另一个进程,自然不会影响我们主进程的结果。有些编译器(VS)会将const变量声明成宏的形式,在使用的时候直接输出结果而不是变量值。

 2.4 dynamic_cast

用于将一个父类对象的指针和引用转换为子类对象的指针或引用。(动态转换)

向上转型:子类对象指针/引用 转换为父类对象指针/引用 (不需要转换,赋值兼容规则,切片)

向下转型:父类对象指针/引用 转子类 (用dynamic_cast转型是安全的)

注意

dynamic_cast只能用于父类中含有虚函数的类。

dynamic_cast会先检查是否能转换成功,能成功就转换,不能返回0

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 = dynamic_cast<b>(aa);
	b bb = (b)aa;*/
	b bb;

	fun(&aa);
	fun(&bb);
	//fun(nullptr);

	return 0;
}

2.4.2 dynamic_cast的意义

如果我们仍然使用C语言中的强制类型转换,不论我传入的pa是子类指针还是父类指针,结果就会都是转换成功。并且当我传入的是父类指针时,解引用出现错误,导致程序终止。

2.4.3 dynamic_cast和强制类型转换的多继承

class A1
{
public:
	virtual void f(){}
public:
	int _a1 = 0;
};


class A2
{
public:
	virtual void f(){}
public:
	int _a2 = 0;
};

class B : public A1, public A2
{
public:
	int _b = 1;
};

 注意强制类型转换也会让指针偏移回去,在这里和dynamic_cast结果是一样的

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值