C++类型转换

Posted JJP不会CPP

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++类型转换相关的知识,希望对你有一定的参考价值。

文章目录

一、C语言的类型转换

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

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

  • 隐式类型转换:一般发生在意义相近的变量之间,比如int类型和double类型的隐式类型转换,这种类型的转换在编译阶段自动进行,如果不能转换就会编译报错。
  • 显式类型转换:一般发生在意义不相近的变量之间,比如int类型和int*类型的转换,这种类型的转换需要用户自己处理。
void Test ()

     int i = 1;
     // 隐式类型转换
     double d = i;
     printf("%d, %.2f\\n" , i, d);
     
     int* p = &i;
     // 显示的强制类型转换
     int address = (int) p;
     printf("%x, %d\\n" , p, address);

C语言的类型转换太过于杂乱,可视性很差,所有的转换形式都是以一种相同形式书写,不能很快地定位具体是什么类型的转换,所以C++提出了自己的类型转换风格,增加了四种命名的强制类型转换操作符:static_castreinterpret_castconst_castdynamic_cast

二、C++的类型转换

1.static_cast

static_cast用于非多态类型的转换(静态转换),C语言中会发生隐式类型转换的变量之间都可以用static_cast进行转换,但它不能用于两个不相关的类型进行转换。

int main()

	double d = 12.34;
	// 下面的语句在C语言中可以不需要指定转换方式,double类型会隐式类型转换成int类型
	// 在C++规范中使用static_cast方式进行转换
	int a = static_cast<int>(d);
  	cout<<a<<endl;
  	return 0;

2.reinterpret_cast

reinterpret_cast用于将一种类型转换为另一种不同的类型。

int main()

	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;
	// 这里使用static_cast会报错,应该使用reinterpret_cast
	//int *p = static_cast<int*>(a);
	int *p = reinterpret_cast<int*>(a);
	return 0;

3.const_cast

const_cast的用途是删除const变量的const属性,通过传递变量的指针或者引用,从而可以更改const变量的值。

void Test ()

	const int a = 2;
  	int* p = const_cast< int*>(&a );
  	*p = 3;
  	cout<<a <<endl;

上面的代码示例输出的a还是2,原因是原先的const变量a是在寄存器中的,编译器直接去寄存器取值,但*p修改的值是在内存中修改的,所以const_cast的类型转换需要加上volatile,要求编译器必须去内存取值,这样最后输出a的结果才是3。

void Test()

    volatile const int a = 2;
    int *p = const_cast<int *>(&a);
    *p = 3;

    cout << a << endl;

4.dynamic_cast

dynamic_cast叫作动态转换,它用于将一个父类对象的指针或者引用转换为子类对象的指针或者引用。

在继承体系中,父类与子类对象指针或引用之间的转换分为向上转换和向下转换(仅限于父子类对象的指针或引用的转换,对象转换是不支持的):

  • 向上转换:子类对象的指针或引用转换成父类对象的指针或引用,会进行切片,语法是支持的。
  • 向下转换:父类对象的指针或引用转换成子类对象的指针或引用,这种转换是不安全的。

dynamic_cast只能用于父类含有虚函数的类,在使用dynamic_cast时它会先检查是否能转换成功,如果能成功则返回转换以后的地址,否则返回0

比如下面的例子,我们定义一个含有虚函数的父类A,再定义一个子类B,fun函数的形参是A类型的,我们想要在fun函数中进行类型转换,将形参的类型转换成B类型。

那么就会有一个问题,我们怎么确定形参传递进来的是A还是B(因为有切片的存在,B*也可以作为实参传递进来,这里会发生向上转换)?

如果形参传递进来的值原本是一个A类型的,它在fun函数内转换成B类型就会出错,转换失败。

如果形参传递进来的值原本是一个B类型的,通过向上转换成A类型的形参,它在fun函数内转换成B*类型就会成功。

所以我们要使用dynamic_cast来判断是否转换成功:

#include <iostream>
#include <memory>

using namespace std;

class A

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

;
void fun(A *pa)

    // dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
    B *pb = dynamic_cast<B *>(pa);

    // 转换失败,说明形参原本的类型是A*
    if(pb == 0)
    
        cout << "转换失败, pb: " << pb << endl; 
    
    else
    
        cout << "转换成功, pb: " << pb << endl; 
    


int main()

    A a;
    B b;
    fun(&a);
    fun(&b);
    return 0;

最后程序的结果是fun(&a)转换失败,fun(&b)转换成功。

以上是关于C++类型转换的主要内容,如果未能解决你的问题,请参考以下文章

C++的类型转换

C++的类型转换

C++类型转换

C++的类型转换

C++的类型转换

C++中的类型转换