C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

下面是关于C++中四种强制类型转换的攻略。

1. static_cast

static_cast是安全的类型转换,主要用于基本数据类型之间的转换,还可以在继承类之间进行类型转换。它可以将一个值从一种数值类型转换为另一种数值类型或提升或降低算术类型的类型。在用于指针时,可以将任何类型的指针转换为void指针,也可以将void指针转换为任何类型的指针。但是,它不能成功执行动态类型检查,也不能在安全性方面进行任何检查。

示例1

以下是一个基本数据类型之间转换的示例:

#include <iostream>

int main() {
    double d = 3.14;
    int i = static_cast<int>(d); //使用静态转换将double转换为int
    std::cout << "d = " << d << ", i = " << i << std::endl;
    //输出:d = 3.14, i = 3
    return 0;
}

示例2

以下是一个继承类之间的类型转换示例:

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void func() {
        std::cout << "Derived::func()" << std::endl;
    }
};

int main() {
    Base* b = new Derived();
    Derived* d = static_cast<Derived*>(b); //用静态类型转换将基类指针指向派生类对象的指针,向下转换
    d->func(); //调用派生类函数
    delete b;
    return 0;
}

这里要注意,使用static_cast进行继承类之间的类型转换时,必须确保基类指向的实际是派生类,否则转换后调用派生类函数可能会出错。

2. dynamic_cast

dynamic_cast是一种动态类型转换,可以用于在继承类之间进行类型转换。它可以用于进行向上转换和向下转换。它会根据实际对象的类型来检查转换是否合法并进行安全检查。如果转换无效,则返回nullptr,如果转换有效,则必须再将其转换为正确的类型指针。

示例1

以下是一个向上转换的示例:

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void func() {
        std::cout << "Derived::func()" << std::endl;
    }
};

int main() {
    Derived d;
    Base* b = &d;
    Derived* d1 = dynamic_cast<Derived*>(b); //向上转换
    if (d1) {
        d1->func();
    }
    return 0;
}

示例2

以下是一个向下转换的示例:

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void func() {
        std::cout << "Derived::func()" << std::endl;
    }
};

int main() {
    Base* b = new Derived();
    Derived* d = dynamic_cast<Derived*>(b); //向下转换
    if (d) {
        d->func();
    }
    delete b;
    return 0;
}

这里要注意,dynamic_cast只能用于类的继承关系中,且要保证基类有虚析构函数。

3. const_cast

const_cast用于将常量指针或常量引用转换为非常量指针或非常量引用。它可以在去除常量性方面进行强制类型转换,但它不能扩大或缩小指针类型,不能在指针类型之间进行转换。

示例1

以下是一个常量引用转换为非常量引用的示例:

#include <iostream>

void func(const int& i) {
    int& j = const_cast<int&>(i);
    j = 10;
    std::cout << "i = " << i << ", j = " << j << std::endl;
}

int main() {
    int n = 5;
    func(n);
    return 0;
}

示例2

以下是一个常量指针转换为非常量指针的示例:

#include <iostream>

int main() {
    const int n = 5;
    const int* p1 = &n;
    int* p2 = const_cast<int*>(p1); //常量指针转换为非常量指针
    *p2 = 10;
    std::cout << "n = " << n << ", *p2 = " << *p2 << std::endl;
    return 0;
}

这里要注意,const_cast用于去除常量性是安全的,但过度使用const_cast可能会引发代码的语义混乱和不良后果。

4. reinterpret_cast

reinterpret_cast可以将一个指针或引用转换为其他类型的指针或引用,包括指向不同类型的指针之间的转换,从任何指针类型到void指针类型的转换等。它只是简单地将指针或引用重新解释为其他类型,而不修改指向的实际对象,因此需要小心使用。

示例1

以下是一个char指针转换为int指针的示例:

#include <iostream>

int main() {
    char c = 'A';
    char* pc = &c;
    int* pi = reinterpret_cast<int*>(pc); //将char指针转换为int指针
    std::cout << "*pi = " << *pi << std::endl;
    return 0;
}

示例2

以下是一个将整数转换为void指针,再将void指针转换回整数的示例:

#include <iostream>

int main() {
    int n = 65;
    void* p = reinterpret_cast<void*>(n); //将整数转换为void指针
    int n2 = reinterpret_cast<int>(p); //将void指针转换为整数
    std::cout << "n2 = " << n2 << std::endl;
    return 0;
}

这里要注意,由于reinterpret_cast可以进行危险的类型转换,因此使用时必须小心,在确保安全的前提下使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast) - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • excel2json软件使用方法(Excel表快速转换成JSON字符串)

    下面为您详细讲解“excel2json软件使用方法”: 简介 excel2json是一款免费开源的轻量级工具,可以将Excel表格快速转换成JSON字符串格式,让开发者们更加便捷地使用表格数据。 下载安装 首先,在excel2json的官网上下载最新的可执行文件。 下载完毕后,解压缩文件并将excel2json.exe程序文件放置到您的电脑合适的位置。此时,…

    C 2023年5月23日
    00
  • C语言中的递归,你真的懂了吗?

    C语言中的递归,你真的懂了吗? 递归是指一个函数不断地调用自己来实现某种功能,通常递归函数都包含一个或多个条件语句,作为递归结束的判断条件。对于初学者来说,递归常常是比较难理解和掌握的一种编程思想。本篇文章将详细讲解如何理解和使用C语言中的递归。 递归的基本原理 递归的基本原理非常简单:将原问题分解成一个或者多个规模较小但是可以解决的子问题,并且将小问题的解…

    C 2023年5月22日
    00
  • 详解C++编程中断言static_assert的使用

    详解C++编程中断言static_assert的使用 在C++中,当我们需要在编译期进行类型检查或常量计算时,可以使用static_assert。具体来说,static_assert是一个语言特性,用于在编译期进行断言判断,如果判断条件为false,则程序会在编译期抛出一个编译错误,阻止程序的继续编译。 用法 static_assert可以用于两种类型的判断…

    C 2023年5月23日
    00
  • C语言数组实现学生信息管理系统设计

    针对这个话题,我将为你详细讲解“C语言数组实现学生信息管理系统设计”的完整攻略。具体过程如下: 第一步:确定学生的信息结构 我们首先需要确定学生的信息结构,也就是每个学生信息需要包含哪些字段。常见字段包括姓名、学号、性别、年龄、联系方式等等。针对这些字段,我们可以使用C语言的结构体来进行定义,如下所示: struct Student { char name[…

    C 2023年5月30日
    00
  • c++中string和vector的详细介绍

    很好,”C++中string和vector的详细介绍”是一个重要的话题,我很乐意为你提供完整的攻略。 1. 概述 1.1 string string 是 C++ STL 中的一个标准库,它用于处理字符串。string 和 C 语言中的字符串类型 char* 相似,但是具有更多的操作和特定属性,比如它们是可以动态增长的。 C++中的string定义方式如下: …

    C 2023年5月23日
    00
  • fork()和exec()的区别

    fork()和exec()的区别 在Linux系统中,fork()和exec()是两个常用的系统调用,它们都与进程有关。但是它们的用途是不同的,这里详细讲解两者的区别。 fork() fork()的作用是创建一个新的进程,新进程是原进程的副本,这个新进程被称为子进程。子进程具有与父进程(即原进程)完全相同的代码和数据,但是其运行状态和内存空间都是独立的,即父…

    C 2023年5月10日
    00
  • 深入解析C++编程中__alignof 与__uuidof运算符的使用

    深入解析C++编程中__alignof 与__uuidof运算符的使用 __alignof 运算符 __alignof 运算符用来获取一个类型所需的对齐宽度,也就是该类型所占空间的整数倍。其语法如下: alignof(type) 其中,type 表示类型,可以是内置类型、用户自定义类型、指针类型、引用类型等。 示例1: #include <iostre…

    C 2023年5月23日
    00
  • C语言 函数

    C语言 函数 使用攻略 什么是函数 在程序设计中,函数是一段可以重复使用的代码块。将一组操作封装在函数中,可以提高代码的可读性和可维护性,并有助于模块化程序设计。 在C语言中,函数由函数头和函数体组成。函数头包含函数名和参数列表,参数列表是一组可以传递给函数的值,函数体包含了具体的操作代码。 函数定义的语法如下: 返回值类型 函数名(参数列表) { // 函…

    C 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部