首页 > 编程语言 >C++编程基础:类型转换四式速记const_cast,dynamic_cast,reinterpret_cast,static_cast

C++编程基础:类型转换四式速记const_cast,dynamic_cast,reinterpret_cast,static_cast

时间:2025-01-07 20:01:22浏览次数:9  
标签:类型转换 std const cast 转换 指针

在这里插入图片描述

C++编程就应该使用C++风格的转换,不要再使用不安全的C风格的转换方法了。这里先给一个C++编程风格的类型转换四式速记打油诗,帮大家记忆其用法:


C++强制转换妙,四类各有其诀窍。
const_cast用途巧,常量限制可取消,
const属性轻松搞,函数参数常需要。

dynamic_cast专长显,继承体系安全检,
基类指针或引用,派生类型能判断,
多态类型转换间,指针失效返空悬。

reinterpret_cast强,内存重释威力扬,
不相关型指针忙,底层操作它帮忙,
谨慎使用别乱闯,风险虽高有时享。

static_cast常规搞,相关类型转换好,
算术类型亦能搞,精度问题要知晓,
编译时检较可靠,隐式转换它代劳。

四种转换细思考,代码正确效能高,
合理运用方为妙,编程之路乐逍遥。


const_cast:常量属性的灵活调整

const_cast用于去除变量的const或volatile限定符,或在两者之间进行转换。这在需要修改原本被定义为常量的数据时非常有用,但需要谨慎使用,因为去除const限定符可能导致未定义行为,如果修改了原本不应被修改的常量。

#include <iostream>

void modifyConstValue() {
    const int const_value = 10;
    // 下面这行代码会产生编译错误,因为试图修改const常量
    // const_value = 20; 

    // 使用const_cast去除const限定符,允许修改值
    int& non_const_ref = const_cast<int&>(const_value);
    non_const_ref = 20;

    std::cout << "Modified value: " << const_value << std::endl; 
    // 输出:Modified value: 20,注意,虽然输出是修改后的值,但这种行为是不推荐的,因为const_value原本被定义为常量
}

dynamic_cast:继承体系中的安全转换

dynamic_cast主要用于在继承体系中进行安全的向下转型(从基类指针或引用转换为派生类指针或引用)。它在运行时检查转换的有效性,如果转换不合法(例如基类指针实际上并不指向派生类对象),则返回null指针(对于指针类型转换)或抛出std::bad_cast异常(对于引用类型转换)。这在处理多态类型时非常重要,可以确保类型转换的安全性,避免错误的指针操作导致程序崩溃。

#include <iostream>
#include <typeinfo>

class Animal {
public:
    virtual void makeSound() {
        std::cout << "Some generic animal sound." << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Woof!" << std::endl;
    }

    void wagTail() {
        std::cout << "Tail is wagging." << std::endl;
    }
};

void processAnimal(Animal* animal) {
    // 使用dynamic_cast尝试将Animal*转换为Dog*
    Dog* dog = dynamic_cast<Dog*>(animal);
    if (dog!= nullptr) {
        dog->wagTail();
    } else {
        std::cout << "Object is not a Dog." << std::endl;
    }
}

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Animal();

    processAnimal(animal1); 
    // 输出:Tail is wagging.,因为animal1实际上指向一个Dog对象,转换成功

    processAnimal(animal2); 
    // 输出:Object is not a Dog.,因为animal2指向一个Animal对象,转换失败,dynamic_cast返回null指针

    delete animal1;
    delete animal2;

    return 0;
}

reinterpret_cast:内存层面的类型重新解释

reinterpret_cast用于执行低级别的、依赖于实现的类型转换,它直接对对象的二进制表示进行重新解释,将一种类型的指针转换为另一种不相关类型的指针,或者将整数类型转换为指针类型,反之亦然。这种转换非常危险,因为它不进行任何类型检查,完全依赖于程序员对内存布局和对象表示的了解。通常只在与硬件接口、底层系统编程或某些特定的优化场景中使用,并且需要极度谨慎,以避免未定义行为和内存错误。

#include <iostream>

int main() {
    int num = 10;
    // 使用reinterpret_cast将int*转换为char*,并逐个字节输出
    char* char_ptr = reinterpret_cast<char*>(&num);
    std::cout << "Bytes of integer 10: ";
    for (int i = 0; i < sizeof(int); ++i) {
        std::cout << static_cast<int>(char_ptr[i]) << " ";
    }
    std::cout << std::endl;

    // 将一个整数转换为指针类型(这种用法在实际中很少见且危险,仅用于演示)
    int address_value = 0x12345678;
    int* int_ptr = reinterpret_cast<int*>(address_value);
    std::cout << "Value at address 0x12345678 (interpreted as int): " << *int_ptr << std::endl;
    // 注意:上面这行代码可能会导致程序崩溃,因为0x12345678可能不是一个有效的可访问内存地址

    return 0;
}

static_cast:常规类型转换的得力助手

static_cast用于执行相关类型之间的转换,这些转换在编译时是已知有效的,例如在算术类型之间进行转换(如int到double)、在具有继承关系的类之间进行向上转型(从派生类指针或引用转换为基类指针或引用)、将void指针转换为其他指针类型,以及进行隐式转换的显式替代。它比C风格的强制类型转换更严格,会进行一些基本的编译时检查,有助于发现一些明显的类型不匹配错误,但对于某些潜在的不安全转换(如数据截断),它仍然可能导致问题,需要程序员自行确保转换的安全性。

#include <iostream>

int main() {
    double double_value = 3.14;
    // 使用static_cast将double转换为int,会截断小数部分
    int int_value = static_cast<int>(double_value);
    std::cout << "Double value: " << double_value << ", Integer value after static_cast: " << int_value << std::endl;

    class Base {
    public:
        virtual void baseFunction() {
            std::cout << "Base function." << std::endl;
        }
    };

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

    Derived derived_obj;
    // 使用static_cast进行向上转型,将Derived*转换为Base*
    Base* base_ptr = static_cast<Base*>(&derived_obj);
    base_ptr->baseFunction(); 
    // 输出:Base function.

    // 使用static_cast进行向下转型,将Base*转换为Derived*(需要确保指针实际指向Derived对象,否则会导致未定义行为)
    Derived* derived_ptr = static_cast<Derived*>(base_ptr);
    derived_ptr->derivedFunction(); 
    // 输出:Derived function.,因为base_ptr实际上指向Derived对象,转换成功

    void* void_ptr = &double_value;
    // 使用static_cast将void*转换为double*
    double* double_ptr = static_cast<double*>(void_ptr);
    std::cout << "Value pointed by double_ptr: " << *double_ptr << std::endl;

    return 0;
}

请注意,在实际编程中,应尽量遵循类型安全原则,谨慎使用强制类型转换,尤其是reinterpret_cast,因为它容易导致难以调试的错误。只有在确实需要进行特定类型转换且明确了解其后果的情况下才使用强制类型转换,并确保转换后的操作是安全和正确的。

标签:类型转换,std,const,cast,转换,指针
From: https://blog.csdn.net/gzjimzhou/article/details/144991891

相关文章

  • docker启动nacos报错: Nacos Server did not start because dumpservice bean constru
    一、docker启动nacos报错:mysql版本:8nacos版本:2.xNacosServerdidnotstartbecausedumpservicebeanconstructionfailure:NoDataSourcesetNacosisstarting,youcandockerlogsyourcontainer+exec/opt/java/openjdk/bin/java-XX:+UseConcMarkSweepGC-XX:+U......
  • 关于const的使用
    1、修饰整型变量constinta就是声明了一种常量表示该变量的内容不可改变2、对于修饰指针的const就有说法了constint*a和int*consta这是两种不同的用法第一种:constint*a表示定义了一个指向const变量的指针,但是指针本身不是const类型,也就是说指针本身可以修改但是指向......
  • Effective C++读书笔记——item2(const,enum,inlines取代#define)
    关于用常量取代#define的总体原则在编程中,应尽量减少预处理器(特别是#define)的使用,可通过合适的替代方式来避免#define带来的诸多问题,虽然不能完全消除预处理器相关指令(如#include、#ifdef/#ifndef仍有重要作用),但要让其使用频率降低。简单常量方面问题阐述:使用#defi......
  • 在 Python 中,如何将日期时间类型转换为字符串?
    在Python中,将日期时间类型转换为字符串可以通过以下几种方式来实现:方法一:使用strftime()方法fromdatetimeimportdatetimenow=datetime.now()formatted_string=now.strftime("%Y-%m-%d%H:%M:%S")print(formatted_string)  strftime()方法可以根据指定的格......
  • JAVA-Day 04:数据类型转换
    类型转换(Typeconversion)byte,short,char—>int—>long—>float—>doouble低---------------------------------------------------------------------->高注意:运算中,不同类型的数据先转化为同一类型,然后进行计算。类型转换(Typeconversion)分为强制转换和自动转换1.强制......
  • 引用与常量 - 引用类型、const关键字
    引言在C++中,引用和const关键字是两个非常重要的概念。引用提供了一种方便的方式来操作变量的别名,而const关键字则用于定义不可修改的常量或指针。正确理解和使用这两个特性可以提高代码的安全性和可读性。本文将详细介绍引用的基本概念和操作,以及const关键字的各种用法,帮助初......
  • 将一个浮点数或任何其他类型的值赋给 unsigned char 类型的变量时,C语言进行类型转换
    C语言中,unsignefcharTemp_Val;Temp_Val=(unsignefchar)rd_temperature();若rd_temperature()函数返回51.7,则Temp_Val等于多少?在C语言中,unsignedchar 类型通常用于存储0到255之间的无符号整数。当你将一个浮点数或任何其他类型的值赋给 unsignedchar 类型的变量时,C语言......
  • C++ 中将 float 类型转换为 std::string
    在C++中,可以使用多种方法将 float 类型转换为 std::string 类型。以下是常用的几种方法:方法1:std::to_string (C++11及以上)这是最简单的方法之一,直接使用 std::to_string。#include<iostream>#include<string>intmain(){floatnum=123.456f;std::......
  • const关键字
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title><......
  • 4.3 类型转换实例
    【例4.5】将图像从BGR模式转换为RGB模式。importcv2importnumpyasnplena=cv2.imread("/Users/zhaofeier/Desktop/lenacolor.png")rgb=cv2.cvtColor(lena,cv2.COLOR_BGR2RGB)cv2.imshow("lena",lena)cv2.imshow("rgb",rgb)cv2.waitKey()......