栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++】类型转换

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++】类型转换

文章目录
    • C语言中的类型转换
      • 隐式类型转换
      • 显示类型转换(强制类型转换)
    • C++强制类型转化
      • static_cast
      • reinterpret_cast
      • const_cast
      • dynamic_cast
    • explicit

C语言中的类型转换

C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化

C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。

隐式类型转换

编译器在编译阶段自动进行,能转就转,不能转就编译失败

适用于相近的类型

void show(int i){
    //参数的接收发生了隐式类型转换
	std::cout << i << std::endl;
}
int main(){
	double d = 1.1;
	show(d);

	return 0;
}
显示类型转换(强制类型转换)

需要用户自己处理,通常用于不相近类型的转换

int main(){
	int a = 0;
	int* p = &a;
    //将指针强制转化为int类型
	int b = (int)p;
}

C++强制类型转化

C语言的类型转化有很大的缺陷:

  • 隐式类型转换可能会因为整形提升或者数据截断导致精度的丢失
  • 隐式类型有时会被程序员忘记或者忽略,造成错误
  • 显式类型转换将所有情况混合在一起,代码不够清晰,如果出现错误不好查

C++为了加强类型转化的规范性和可视性,引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast、dynamic_cast


static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。(即对应C语言中的隐式类型转换)

int main(){
	double d = 1.1;
    //可以让隐式类型转化更加规范
	int a = static_cast(d);
	std::cout << i;
}

reinterpret_cast

reinterpret_cast是一种较为危险的类型转换,通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型,通常适用于指针、引用、以及整数之间的类型转换。对应C语言的强制类型转化

int main(){

	int a = 998;
	int* p1 = &a;

	//这里的强制类型转化,是把int指向的空间强制转化成了double指向的空间
	//所以p1以前读取四个字节内容,转换后p2可以读取八个字节内存,所以p1在转换后指向的内容发生了变化
	double* p2 = reinterpret_cast(p1);

	std::cout << *p2 < 


const_cast

通常用于删除变量的const属性

int main(){
	
    //const变量会被编译器优化放到寄存器,加上volatile防止编译器优化
	volatile const int a = 2;
	int* p = const_cast(&a);

	*p = 3;

	std::cout << a << std::endl;
	std::cout << *p << std::endl;

	return 0;
}

dynamic_cast

将基类的指针或引用安全地转换成派生类的指针或引用

基类和派生类之间的转换分为两种

  • 向上转型:子类对象指针/引用->父类指针/引用(切片,原生支持的)
  • 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

dynamic_cast的向下转换``只支持继承中的多态类型,也就是父类之中必须包含虚函数

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

class B : public A{
public:
	virtual void f() {
		cout << "f()::B" << endl;
	}

	void showB() {
		cout << "showB()::B" << endl;
	}
};

int main() {
	
	A* pa = new B;
	//把基类指针强制转换为派生类指针
	B* pb = dynamic_cast(pa);
	
    //转换时会做安全检查,如果不能成功转换就会返回0
	if (pb) {
		pb->showB();
	}
	return 0;
}
  • dynamic_cast只能用于含有虚函数的类
  • dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

explicit

在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换

class A{
public:
	explicit A(int a){
		cout << "A(int a)" << endl;
	}
private:
	int _a;
};
int main(){
	A a1(1);
	// 隐式转换-> A tmp(1); A a2(tmp);
	A a2 = 1;
}

a2使用赋值进行初始化,其实是先把1隐式类型转换为一个临时对象,然后用临时对象对a2进行赋值

使用explicit关键字修饰构造函数,A就不会进行隐式类型转换

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1009859.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号