C++零基础教程(新式类型转换)

简介: C++零基础教程(新式类型转换)

前言

本篇文章我们来讲解C++中的新式类型转换,在C语言中遇到类型转换我们一般使用强制类型转换,但是这种转换的方式是不安全的,可能会导致截断的发生,C++引入的新式类型转换解决了这个问题。

C++中的新式类型转换是一种更加安全和灵活的类型转换方法,它提供了四种不同的转换操作符,分别是static_cast、dynamic_cast、reinterpret_cast和const_cast。每种转换操作符都有其特定的用途和限制。

一、static_cast

static_cast用于基本类型之间的转换,以及非多态类型的转换,如指针或引用的类型转换。它具有以下特点:

用于常见的转换操作,如数值类型之间的转换、隐式转换和父子类之间的指针或引用转换。

// 数值类型之间的转换
int num = 10;
double convertedNum = static_cast<double>(num);
// 父子类之间的指针转换
class Base {
public:
    virtual ~Base() {}
};
class Derived : public Base {
public:
    void foo() {
        cout << "Derived::foo()" << endl;
    }
};
Base* basePtr = new Derived();
Derived* derivedPtr = static_cast<Derived*>(basePtr);
derivedPtr->foo();

二、dynamic_cast

dynamic_cast主要用于多态类型之间的转换,即在类继承关系中进行转换。它具有以下特点:

用于在继承关系中的指针或引用之间进行转换,并进行运行时类型检查。如果转换合法,返回目标类型的指针或引用;如果转换不合法,返回nullptr或引发std::bad_cast异常。

只能用于具有虚函数的类的转换,即运行时类型识别(RTTI)可用的类。

对于指针类型,如果指针为nullptr,转换结果也为nullptr。

转换操作开销较大,涉及动态类型信息查询和检查。

// 多态类型之间的转换
class Base {
public:
    virtual ~Base() {}
    virtual void foo() {
        cout << "Base::foo()" << endl;
    }
};
class Derived : public Base {
public:
    void foo() {
        cout << "Derived::foo()" << endl;
    }
};
Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr != nullptr) {
    derivedPtr->foo();
} else {
    cout << "Dynamic Cast failed." << endl;
}

三、reinterpret_cast

reinterpret_cast用于进行低层次的类型转换,它几乎可以将任何指针或整数类型转换为任意其他类型。它具有以下特点:

用于执行与指针无关的类型之间的转换,如指针和整数之间的转换,以及指针类型之间的转换。

不进行类型检查,提供了最大的灵活性,但也潜在地破坏了类型系统和安全性。

在正常情况下,应避免使用reinterpret_cast,因为它可能导致未定义的行为。

// 指针和整数类型之间的转换
int num = 10;
int* numPtr = &num;
uintptr_t address = reinterpret_cast<uintptr_t>(numPtr);
cout << "Address: " << address << endl;
int* restoredPtr = reinterpret_cast<int*>(address);
cout << "Restored Value: " << *restoredPtr << endl;

四、const_cast

const_cast用于添加或删除指针或引用的const属性。它具有以下特点:

主要用于处理const和非const之间的转换,以提供对常量对象的非常量访问或对非常量对象的常量访问。

不能用于转换掉对象的const属性,这样的转换是未定义行为。

改变了类型修饰符,但不能执行实际的对象或值的转换。

// 添加或删除const属性
const int num = 10;
int& numRef = const_cast<int&>(num); // 移除const属性
numRef = 20;
const int* constPtr = &num;
int* mutablePtr = const_cast<int*>(constPtr); // 移除const属性
*mutablePtr = 30;
cout << "Modified num: " << num << endl; // 输出为20

总结

本篇文章就讲解到这里,新式类型转换大家必须掌握好。


相关文章
|
12天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
40 5
|
2月前
|
算法 数据挖掘 Shell
「毅硕|生信教程」 micromamba:mamba的C++实现,超越conda
还在为生信软件的安装配置而烦恼?micromamba(micromamba是mamba包管理器的小型版本,采用C++实现,具有mamba的核心功能,且体积更小,可以脱离conda独立运行,更易于部署)帮你解决!
66 1
|
2月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
44 1
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
20 1
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
31 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
47 3
|
2月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
279 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
2月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
21 0
|
5月前
|
存储 安全 编译器
【C++11】类型转换
【C++11】类型转换
30 0
|
5月前
|
安全 程序员 编译器
C++一分钟之-C++中的类型转换
【7月更文挑战第8天】C++中的类型转换涉及隐式和显式操作,隐式转换如从`int`到`double`是自动的,但可能导致数据丢失。显式转换包括`static_cast`, `dynamic_cast`, `const_cast`, `reinterpret_cast`,以及转换构造函数。要避免数据丢失、类型不匹配和运行时错误,需谨慎使用显式转换并检查结果。过度使用`reinterpret_cast`应避免。理解这些转换有助于编写更安全的代码。
45 0