【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast

这篇具有很好参考价值的文章主要介绍了【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言


💡 作者简介:专注于C/C++高性能程序设计和开发,理论与代码实践结合,让世界没有难学的技术。包括C/C++、Linux、MySQL、Redis、TCP/IP、协程、网络编程等。
👉
🎖️ CSDN实力新星,社区专家博主
👉
🔔 专栏介绍:从零到c++精通的学习之路。内容包括C++基础编程、中级编程、高级编程;掌握各个知识点。
👉
🔔 专栏地址:C++从零开始到精通
👉
🔔 博客主页:https://blog.csdn.net/Long_xu


🔔 上一篇:【035】C++泛型编程(模板)实践:设计数组类模板模仿vector容器

一、类型转换简介

标准C++提供了一个显式的转换语法,用来代替C语言风格的类型转换。使用C语言风格的强制转换可以把想要的任何东西转换成我们需要的类型。

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同类型的强制转换。
C++风格的强制转换的好处:能更清晰的表明它们要干什么。开发者只要看一眼这样的代码,就能够立即知道一个强制转换目的。

C++中的类型转换允许将一个数据类型转换为另一个数据类型。C++提供了多种类型转换操作符和函数来执行不同类型之间的转换。

以下是C++中常见的类型转换方式:

  1. 隐式类型转换(Implicit Type Conversion):也称为自动类型转换,是编译器隐式地执行的类型转换。这种转换是安全的,可以由编译器自动完成,无需显式指定。例如,将一个整数赋值给一个浮点数变量,编译器会自动将整数转换为浮点数。

  2. 显式类型转换(Explicit Type Conversion):也称为强制类型转换,是通过使用转换操作符或函数来显式指定类型转换的方式。显式类型转换可能会导致数据丢失或精度损失。C++提供了以下三种显式类型转换方式:

    • 静态转换(static_cast):用于基本数据类型之间的转换,以及具有继承关系的指针和引用之间的转换。
    • 动态转换(dynamic_cast):用于具有继承关系的类之间的转换,可以在运行时检查类型转换的有效性。
    • 常量转换(const_cast):用于去除指针或引用的常量属性。
  3. 重新解释转换(reinterpret_cast):用于将一个指针或引用转换为另一个不相关类型的指针或引用,这是一种非常危险的转换,需要谨慎使用。

类型转换应该在必要时使用,并且要确保转换的安全性。错误的类型转换可能导致数据丢失、不可预料的行为或程序崩溃。所以,在进行类型转换时,一定要了解数据类型的特点,并谨慎选择适当的转换方式。

二、上行、下行转换的概述

在C++中,上行转换(upcasting)和下行转换(downcasting)是指在继承关系中的类型转换。

  1. 上行转换(Upcasting):将派生类指针或引用转换为基类指针或引用。上行转换是安全的,因为派生类对象中包含了基类对象的所有成员。上行转换是隐式的,不需要显式指定,编译器会自动完成。例如,如果有一个基类Animal和一个派生类Dog,那么可以将Dog对象的指针或引用赋值给Animal对象的指针或引用。

  2. 下行转换(Downcasting):将基类指针或引用转换为派生类指针或引用。下行转换是不安全的,因为基类对象中可能没有派生类特有的成员。下行转换必须显式指定,并且需要使用dynamic_cast运算符进行类型检查。在运行时,dynamic_cast会检查转换是否有效,如果转换无效,返回空指针(对于指针)或引发std::bad_cast异常(对于引用)。例如,如果有一个基类Animal的指针或引用,可以使用dynamic_cast将其转换为派生类Dog的指针或引用。

下行转换只有在确保基类对象指向的是派生类对象时才能安全进行。否则,进行下行转换可能会导致未定义的行为或程序崩溃。因此,在进行下行转换时,最好先使用dynamic_cast进行类型检查,以确保转换的有效性。
【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast,C++从零开始到精通,c++,开发语言,数据结构,C++11,类型转换,vscode

三、static_cast 静态类型转换

static_cast 用于类层次结构中基类(父类)和派生类(子类)之间指针和引用的转换。它支持:

  • 基本类型。
  • 上行转换。
  • 下行转换。

不支持不相干类型转换。

假设存在这样的类:

class Base{
};
class Son:public Base{
};

class Other{
};

(1)支持基本类型。

int num=static_cast<int>(3.1415);// ok

(2)支持上行转换,安全。

Base *p=static_cast<Base *>(new Son);// ok

(3)支持下行转换,不安全。

Son *p=static_cast<Son *>(new Base);// ok

(4)不支持不相关类型的转换。

Base *p=static_cast<Base *>(new Other);// error

【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast,C++从零开始到精通,c++,开发语言,数据结构,C++11,类型转换,vscode

完整示例:

#include <iostream>
using namespace std;

class Base {
};
class Son :public Base {
};

class Other {
};

int main()
{
	int num = static_cast<int>(3.1415);// ok
	Base *p = static_cast<Base *>(new Son);// ok
	Son *p2 = static_cast<Son *>(new Base);// ok
	//Base *p = static_cast<Base *>(new Other);// error
	return 0;
}

四、dynamic_cast 静态类型转换(推荐使用)

dynamic_cast 主要用于类层次间的上行转换和下行转换。一种最安全的类型转换。

假设存在这样的类:

class Base{
};
class Son:public Base{
};

class Other{
};

(1)不支持基本类型。

int num=dynamic_cast<int>(3.1415);// error

(2)支持上行转换,安全。

Base *p=dynamic_cast<Base *>(new Son);// ok

(3)不支持下行转换,不安全。

Son *p=dynamic_cast<Son *>(new Base);// error

(4)不支持不相关类型的转换。

Base *p=dynamic_cast<Base *>(new Other);// error

完整示例:

#include <iostream>
using namespace std;

class Base {
};
class Son :public Base {
};

class Other {
};

int main()
{
	int num = dynamic_cast<int>(3.1415);// error
	Base *p = dynamic_cast<Base *>(new Son);// ok
	Son *p2 = dynamic_cast<Son *>(new Base);// error
	Base *p3 = dynamic_cast<Base *>(new Other);// error
	return 0;
}

报错效果:
【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast,C++从零开始到精通,c++,开发语言,数据结构,C++11,类型转换,vscode

五、const_cast 常量转换

语法:

const_cast< new-type expression>(...)		

返回new-type类型的值。

用途:

  • 将const修饰的指针或引用转换成非const。
  • 将非const修饰的指针或引用转换成const。
const int *p;
int *p2=const_cast<int *>(p);

const int &ob=10;
int &ob2=const_cast<int &>(ob);

int *p3;
const int *p4=const_cast<int *>(p3);

int ob3=10;
const int &ob4=const_cast<int &>(ob3);

const_cast只能进行以下转换。特别是,只有const_cast可用于抛弃(去除)恒常性或波动性。

(1)指向同一类型的两个可能的多级指针可以相互转换,而不必考虑每个级别上的cv限定符。

(2)任何类型的左值都可以转换为相同类型的左值或右值引用,或多或少受cv限制。同样,类类型的右值或任何类型的右值都可以转换为或多或少限定cv的右值引用。如果表达式是一个全局值,则引用const_cast的结果指向原始对象,否则指向物化的临时对象。

(4)同样的规则也适用于可能指向数据成员的多级指针,以及可能指向具有已知和未知边界的数组的多级指针(指向限定cv的元素的数组本身也被认为是限定cv的)。

(5)空指针值可以转换为new-type的空指针值。

示例:

#include <iostream>
 
struct type
{
    int i;
 
    type(): i(3) {}
 
    void f(int v) const
    {
        // this->i = v;                 // compile error: this is a pointer to const
        const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
    }
};
 
int main()
{
    int i = 3;                 // i is not declared const
    const int& rci = i;
    const_cast<int&>(rci) = 4; // OK: modifies i
    std::cout << "i = " << i << '\n';
 
    type t; // if this was const type t, then t.f(4) would be undefined behavior
    t.f(4);
    std::cout << "type::i = " << t.i << '\n';
 
    const int j = 3; // j is declared const
    [[maybe_unused]]
    int* pj = const_cast<int*>(&j);
    // *pj = 4;      // undefined behavior
 
    [[maybe_unused]]
    void (type::* pmf)(int) const = &type::f; // pointer to member function
    // const_cast<void(type::*)(int)>(pmf);   // compile error: const_cast does
                                              // not work on function pointers
}

六、reinterpret_cast 重新解释转换(最不安全)

不支持基本类型,但是支持基本类型指针,而且其他的基本都支持,所以是最不安全的。
假设存在这样的类:

class Base{
};
class Son:public Base{
};

class Other{
};

(1)不支持基本类型,但支持基本类型指针。

int num=reinterpret_cast<int>(3.1415);// error
float *q;
int *p=reinterpret_cast<int *>(q);// ok

【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast,C++从零开始到精通,c++,开发语言,数据结构,C++11,类型转换,vscode

(2)支持上行转换。

Base *p=reinterpret_cast<Base *>(new Son);// ok

(3)支持下行转换。

Son *p=reinterpret_cast<Son *>(new Base);// ok

(4)支持不相关类型的转换。

Base *p=reinterpret_cast<Base *>(new Other);// ok

完整示例:

#include <iostream>
using namespace std;

class Base {
};
class Son :public Base {
};

class Other {
};

int main()
{
	int num = reinterpret_cast<int>(3.1415);// error
	float q = 3.16f;
	float *q2 = &q;
	int *num2 = reinterpret_cast<int *>(q2);// ok

	Base *p = reinterpret_cast<Base *>(new Son);// ok
	Son *p2 = reinterpret_cast<Son *>(new Base);// ok
	Base *p3 = reinterpret_cast<Base *>(new Other);// ok
	return 0;
}

总结

  1. 静态类型转换

静态类型转换是最常用的类型转换方式,它可以将一种类型的数据强制转换为另一种类型,但需要注意的是,这种转换可能会损失一些信息,因此在进行此类转换时应当谨慎。

例如:

int a = 10;
double b = static_cast<double>(a);
  1. 动态类型转换

动态类型转换主要用于多态类型之间的转换,它可以将基类指针或引用转换为派生类指针或引用。如果进行非法的类型转换,动态类型转换会返回一个空指针。

例如:

class Base {};
class Derived : public Base {};
Base* base = new Derived;
Derived* derived = dynamic_cast<Derived*>(base);
  1. 重新解释类型转换

重新解释类型转换可以将一个对象的二进制表示重新解释为另一种类型的对象,这种转换通常用于底层编程和特殊的系统级程序中。

例如:

int a = 100;
float b = reinterpret_cast<float&>(a);
  1. const_cast转换

const_cast转换可以将const限定符添加或移除,以便在需要更改底层值时使用,但要注意的是,const_cast转换可能会导致未定义行为。

例如:

const int a = 100;
int& b = const_cast<int&>(a);

【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast,C++从零开始到精通,c++,开发语言,数据结构,C++11,类型转换,vscode文章来源地址https://www.toymoban.com/news/detail-526526.html

到了这里,关于【036】读懂C++的强制类型转换static_cast、const_cast、dynamic_cast以及reinterpret_cast的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • srand(static_cast<unsigned>(time(NULL)))

    srand(static_castunsigned(time(NULL))) 在 C++ 中是用来初始化随机数生成器的代码。 这段代码中, time(NULL) 返回系统当前时间距离 Epoch(Unix 时间的起始时间,通常是1970年1月1日 00:00:00 UTC)的秒数,用 NULL 表示不考虑时区的情况下获取当前时间。然后,将这个时间值传递给 srand 函数,

    2024年02月07日
    浏览(7)
  • C++的类型转换运算符:dynamic_cast

    顾名思义,与静态类型转换相反,动态类型转换在运行阶段(即应用程序运行时)执行类型转换。 可检查 dynamic_cast 操作的结果,以判断类型转换是否成功。使用 dynamic_cast 运算符的典型语法如下: 例如: 如上述代码所示,给定一个指向基类对象的指针,程序员可使用 dyna

    2024年02月15日
    浏览(13)
  • c++面试——强制类型转换

    方式 说明 示例 static_cast 用于基本类型之间、类继承体系之间的转换 int - double Derived* - Base* const_cast 用于移除变量的const、volatile等属性 const int - int dynamic_cast 用于类继承体系之间的安全向下转换,转换失败返回NULL Derived* - Base* reinterpret_cast 用于不相关类型之间的转换,结果不安

    2023年04月25日
    浏览(15)
  • C++强制类型转换

    static_cast 是 C++ 中的一种显式类型转换运算符。 它可以将一个表达式强制转换为指定的类型,并且是静态类型转换,因此不会执行任何运行时类型检查。如果类型转换不合法,则程序可能出现未定义的行为。因此,使用 static_cast 要特别小心,确保类型转换的合法性。 格式

    2024年02月07日
    浏览(10)
  • C++ 强制类型转换

    在C++中,有四种强制类型转换: 1、 static_cast :这是最常见的类型转换。它可以用于基本数据类型之间的转换,也可以用于指向父类和子类之间的指针或引用的转换。 static_cast可以实现下列转换: ①基本数据类型之间的转换。 ②将任何类型转换为void类型。 ③把空指针转换成

    2024年02月14日
    浏览(8)
  • 【C++】dynamic_cast 进行类型转换步骤以及底层实现

    dynamic_cast 是 C++ 中的一种类型转换方式,它可以在运行时进行类型检查, 用于将一个指针或引用强制转换为另一个类型的指针或引用 。dynamic_cast 能够进行安全的向下转型,即将一个基类指针或引用转换为派生类指针或引用。如果转换成功,dynamic_cast 返回转换后的指针或引用

    2023年04月25日
    浏览(15)
  • 【C++】四种强制类型转换

    C++中有四种强制类型转换: 静态转换:static_cast、动态转换:dynamic_cast、重新解释:reinterpret_cast、常量转换(去常性):const_cast 1.静态转换(static_cast):可以用于 基本数据 类型之间的转换,也可以将基类指针或引用转换为派生类指针或引用,但是转换时需要保证类型转换是

    2024年02月06日
    浏览(12)
  • c++ 11 新特性 不同数据类型之间转换函数之reinterpret_cast

    c++ 11 新特性 不同数据类型之间转换函数之reinterpret_cast

    一.不同数据类型之间转换函数 reinterpret_cast 介绍 reinterpret_cast 是C++中的一种类型转换操作符,用于执行低级别的位模式转换。具体来说, reinterpret_cast 可以实现以下功能: 指针和整数之间的转换 :这种转换通常用于在指针中存储额外信息,或者在特定平台上进行底层操作。

    2024年03月09日
    浏览(16)
  • C++强制类型转换详解:四种操作符解析与实例演示

    C++强制类型转换详解:四种操作符解析与实例演示

      概述: C++中的强制类型转换是实现数据类型间转换的关键机制,包括static_cast、dynamic_cast、const_cast和reinterpret_cast四种。这些操作符适用于不同的场景,通过实例源代码详细阐述了它们的使用方法和步骤。 在C++中,强制类型转换是将一个数据类型的值转换为另一个数据类型

    2024年03月09日
    浏览(12)
  • c++中static静态成员变量和静态成员函数、explcit和隐式类型转换、友元函数()详解

    声明为 static 的类成员 称为 类的静态成员 ,用 static 修饰的 成员变量 ,称之为 静态成员变量 ;用 static 修饰 的 成员函数 ,称之为 静态成员函数 。 静态成员变量一定要在类外进行初始化   静态成员 为 所有类对象所共享 ,不属于某个具体的对象,存放在静态区   静态成

    2024年02月04日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包