【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<int>(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<double*>(p1);

	std::cout << *p2 <<std::endl<< *p1;
}

【C++】类型转换_第1张图片


const_cast

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

int main(){
	
    //const变量会被编译器优化放到寄存器,加上volatile防止编译器优化
	volatile const int a = 2;
	int* p = const_cast<int*>(&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<B*>(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;
}

【C++】类型转换_第2张图片

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

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

你可能感兴趣的:(C++,c++,开发语言)