C++ 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等

C++ 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等

flyfish

0. 隐式转换(Implicit Conversions)

隐式转换是编译器自动进行的类型转换,通常在需要将一个类型转换为另一个类型以匹配函数参数、赋值或比较时发生。
示例:

cpp 复制代码
#include <iostream>

void printInt(int i) {
    std::cout << "Implicitly converted to int: " << i << std::endl;
}

int main() {
    char c = 'A'; // char类型
    printInt(c); // char类型隐式转换为int类型
    return 0;
}

在这个例子中,字符类型char被隐式转换为整数类型int以匹配函数参数类型。

1. C-Style Casts (C风格的转换)

C风格的转换使用括号进行类型转换。这种转换方式功能强大,但缺乏类型安全性,可能导致难以发现的错误。
示例:

cpp 复制代码
#include <iostream>

int main() {
    double d = 9.99;
    int i = (int)d; // C-Style Cast
    std::cout << "C-Style Cast: " << i << std::endl;
    return 0;
}

2. C++风格的转换运算符

static_cast

static_cast用于在相关类型之间进行显式转换,例如从基类指针转换为派生类指针,或者从int转换为double
示例:

cpp 复制代码
#include <iostream>

int main() {
    double d = 9.99;
    int i = static_cast<int>(d);
    std::cout << "static_cast: " << i << std::endl;
    return 0;
}
const_cast

const_cast用于移除或添加const属性。

  • 移除 const 属性:使用 const_castconst 对象转换为非 const 对象,通常用于将 const 对象传递给只能接受非 const 对象的函数。

  • 添加 const 属性:使用 const_cast 将非 const 对象转换为 const 对象,通常用于将非 const 对象传递给只能接受 const 对象的函数。
    示例:

移除 const 属性的示例:
cpp 复制代码
#include <iostream>

// 打印非const整型值的函数
void printNonConst(int* x) {
    *x = 20; // 修改非const整型值
    std::cout << "Modified value: " << *x << std::endl;
}

int main() {
    const int i = 10; // 定义const整型值
    // 使用const_cast移除const属性
    printNonConst(const_cast<int*>(&i));
    return 0;
}

在这个例子中,printNonConst函数接受一个非constint指针,并修改该值。我们在main函数中定义了一个const整型变量i,然后使用const_cast将其const属性移除,以便将其传递给printNonConst函数进行修改。

添加 const 属性的示例:
cpp 复制代码
#include <iostream>

// 打印const整型值的函数
void printConst(const int* x) {
    std::cout << "Const value: " << *x << std::endl;
}

int main() {
    int i = 10; // 定义非const整型值
    // 使用const_cast添加const属性
    printConst(const_cast<const int*>(&i));
    return 0;
}

在这个例子中,printConst函数接受一个constint指针,并打印该值。我们在main函数中定义了一个非const整型变量i,然后使用const_cast添加其const属性,以便将其传递给printConst函数。

reinterpret_cast

reinterpret_cast用于转换任意类型的指针。它不会检查被转换的类型是否相关,因此需要谨慎使用。
示例:

cpp 复制代码
#include <iostream>

int main() {
    int i = 10;
    void* p = &i;
    int* ip = reinterpret_cast<int*>(p);
    std::cout << "reinterpret_cast: " << *ip << std::endl;
    return 0;
}
dynamic_cast

dynamic_cast用于在继承层次结构中进行安全的类型转换,只能用于指向多态类型的指针或引用。
示例:

cpp 复制代码
#include <iostream>

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

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

int main() {
    Base* base = new Derived();
    Derived* derived = dynamic_cast<Derived*>(base);
    if (derived) {
        derived->sayHello();
    } else {
        std::cout << "dynamic_cast failed" << std::endl;
    }
    delete base;
    return 0;
}

3. Conversion Operators (转换运算符)

从类的对象转换为指定的基本类型或其他类类型

类可以定义成员函数operator type(),实现对象到其他类型的转换。

用户定义的转换通过构造函数和转换运算符实现,允许将类对象转换为内置类型或其他类类型。
示例:

cpp 复制代码
#include <iostream>

class Integer {
    int value;
public:
    Integer(int v) : value(v) {}
    operator int() const {
        return value;
    }
};

int main() {
    Integer integer(42);
    int i = integer; // 自动调用转换运算符
    std::cout << "Conversion Operator: " << i << std::endl;
    return 0;
}

4. Explicit Conversion Operators (显式转换运算符)

类似于转换运算符,但加上了explicit关键字,防止了隐式转换。这通常用于只有一个参数的转换运算符,以避免意外的类型转换

通过explicit关键字,防止隐式转换。
示例:

cpp 复制代码
#include <iostream>

class Integer {
    int value;
public:
    Integer(int v) : value(v) {}
    explicit operator int() const {
        return value;
    }
};

int main() {
    Integer integer(42);
    // int i = integer; // 这行会编译错误,因为转换运算符是显式的
    int i = static_cast<int>(integer); // 需要显式转换
    std::cout << "Explicit Conversion Operator: " << i << std::endl;
    return 0;
}

5. 模板特化(Template Specialization)

模板特化允许为特定类型提供定制的实现,通常用于为特定类型定制转换逻辑。
示例:

cpp 复制代码
#include <iostream>

template<typename T>
class Converter {
public:
    static void convert(const T& value) {
        std::cout << "Generic conversion: " << value << std::endl;
    }
};

// 对int类型进行特化
template<>
class Converter<int> {
public:
    static void convert(const int& value) {
        std::cout << "Specialized conversion for int: " << value << std::endl;
    }
};

int main() {
    Converter<double>::convert(3.14); // 使用泛型转换
    Converter<int>::convert(42); // 使用特化转换
    return 0;
}

输出

cpp 复制代码
Generic conversion: 3.14
Specialized conversion for int: 42

在这个例子中,定义了一个模板类Converter,并对int类型进行了特化,以提供定制的转换逻辑。

相关推荐
DogDaoDao4 分钟前
leetcode 面试经典 150 题:矩阵置零
数据结构·c++·leetcode·面试·矩阵·二维数组·矩阵置零
计科土狗1 小时前
前缀和与差分
c++·算法
午言若3 小时前
MYSQL 架构
c++·mysql
WPG大大通3 小时前
基于DIODES AP43781+PI3USB31531+PI3DPX1207C的USB-C PD& Video 之全功能显示器连接端口方案
c语言·开发语言·计算机外设·开发板·电源·大大通
羑悻的小杀马特4 小时前
【AIGC篇】畅谈游戏开发设计中AIGC所发挥的不可或缺的作用
c++·人工智能·aigc·游戏开发
闻缺陷则喜何志丹4 小时前
【C++动态规划】1105. 填充书架|2104
c++·算法·动态规划·力扣·高度·最小·书架
析木不会编程5 小时前
【C语言】动态内存管理:详解malloc和free函数
c语言·开发语言
达帮主5 小时前
7.C语言 宏(Macro) 宏定义,宏函数
linux·c语言·算法
茶猫_5 小时前
力扣面试题 39 - 三步问题 C语言解法
c语言·数据结构·算法·leetcode·职场和发展
初学者丶一起加油5 小时前
C语言基础:指针(数组指针与指针数组)
linux·c语言·开发语言·数据结构·c++·算法·visual studio