C++中四种强制类型转换的方式

本文详细介绍了C++中的四种强制类型转换:static_cast用于基本类型和指针类型转换,const_cast处理常量性,reinterpret_cast用于指针和整型的转换,而dynamic_cast确保了类内下行转换的安全性。特别关注了不同转换的适用场景和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++中四种强制类型转换的方式

参考引用:C++强制类型转换操作符 dynamic_cast - 狂奔~ - 博客园 (cnblogs.com)

【C++】static_cast基本用法(详细讲解)_c++ static_cast-优快云博客

C++强制类型转换-优快云博客

1、static_cast

用法场景

(1)用于基本数据类型之间的转换,比如将double转换为int,float转换为double等。

double d = 5.5;
int i = static_cast<int>(d);  // i = 5

(2)将指向派生类的指针转换为基类的指针,也就是上行转换,编译器会在编译的时候检查这个派生类是否是基类的子类,所以转换的过程是安全的。

class Base {};
class Derived : public Base {};
Derived derivedObj;
Base* basePtr = static_cast<Base*>(&derivedObj);

(3)将指向基类的指针转换为派生类的指针,也就是下行转换,编译器没有进行动态类型检查,所以是不安全的,应该使用dynamic_cast

Base* basePtr = new Base();
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 不安全!

(4)在有关联的类型之间进行转换,比如转换枚举值为整数

enum Color { RED, GREEN, BLUE };
int value = static_cast<int>(GREEN);  // value = 1

(5)将其它类型的指针转换为void*指针,比如将int类型的指针转换为void型的指针

int *a;
void* b = static_cast<void*>a;

2、const_cast

用法场景
#include<iostream>
using namespace std;
 
int main()
{
    int a = 10;
 
    const int * p = &a; //常量指针

    //*p = 20;//报错,常量指针不能修改指向的内容
 
    int *q;
 
    q = const_cast<int *>(p);
 
    *q = 20;    //使用const_cast转换之后,可以修改
    cout <<a<<" "<<*p<<" "<<*q<<endl;
 
    cout <<&a<<" "<<p<<" "<<q<<endl;
    //指向的地址一样
    return 0;
}
注意

1、const_cast无法去除变量的常量性,如下所示:

const int a = 10;
int b = const_cast<int>(a);  //compile error

2、使用时要注意,将常量指针进行常量性去除赋值给别的指针之后,别的指针就和原指针共享这块内存,这块内存就不安全了,所以要小心使用

3、reinterpret_cast

用法场景

(1)指针之间类型的转换

int *a = new int;
double *d = reinterpret_cast<double *>(a);

(2)指针转换成整形,但是要注意转换的时候一定要转换到足够长的整形类型中,指针在16、32、64位操作系统下大小分别为2、4、8字节,所以在转换的时候至少要转换到对应大小的整形。

//在64位系统下测试
int b = 0;
int* a = &b;
cout<<__SIZEOF_INT__<<endl; //4
cout<<__SIZEOF_LONG__<<endl; //8
cout<<__SIZEOF_POINTER__<<endl; //8
//int convertedValueint = reinterpret_cast<int>(a); //错误,因为指针大小为8字节,int大小只为4字节
long convertedValue = reinterpret_cast<long>(a);  // 将 int* 指针转换为 long正确

(3)整形转换为指针

int b = 0;
int* a = reinterpret_cast<int*>(b);

4、dynamic_cast

前面我们讲到了static_cast无法保证类内下行转换的安全性,dynamic_cast就做到了动态类型检查,所以就能够保证下行转换的安全性。下行转换又分两种情况,一种是基类指针指向派生类型,然后进行转换,这种转换是安全的,第二种情况是基类指针指向基类类型,这种转换就需要进行动态运行检查,转换失败,会返回NULL。

#include "stdafx.h"
#include<iostream>
using namespace std;

class Base
{
public:
    Base(){};
    virtual void Show(){cout<<"This is Base calss";}
};
class Derived:public Base
{
public:
    Derived(){};
    void Show(){cout<<"This is Derived class";}
};
int main()
{    
    //这是第一种情况
    Base* base = new Derived;
    if(Derived *der= dynamic_cast<Derived*>(base))
    {
        cout<<"第一种情况转换成功"<<endl;
        der->Show();
        cout<<endl;
    }
    //这是第二种情况
    Base * base1 = new Base;
    if(Derived *der1 = dynamic_cast<Derived*>(base1))
    {
        cout<<"第二种情况转换成功"<<endl;
        der1->Show();
    }
    else 
    {
        cout<<"第二种情况转换失败"<<endl;
    }

    delete(base);
    delete(base1);
    system("pause");
}

上面代码中,第二种情况将会转换失败,因为第二种情况的基类指针指向了基类,dynamic_cast只有基类指针指向派生类的时候,才能转换成功。还有个要注意的点是在类层次之间进行指针转换的时候,dynamic_cast只能在具有多态性的类层次结构中进行向下转换,也就是基类至少要含有一个虚函数。

​ 引用的转换规则与指针的转换规则类似,但是引用转换失败并不会返回null,因为没有空引用的概念,引用转换失败会抛出一个bad_cast的异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值