C++ 类型转换运算符

与C++中的其他方法相比,使用命名强制转换被认为是C++中类型转换更安全可靠的方法。在C++中,有四种主要的命名类型转换表达式:

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast

C++ static_cast

我们使用 static_cast 进行标准类型转换,例如从 float 转换为 int

让我们看一个例子。

#include <iostream>
using namespace std;

int main() {
    float my_float = 3.14;
    
    // convert float to int
    int my_int = static_cast<int>(my_float);
    cout << "Float: " << my_float << " -> Int: " << my_int << endl;

    return 0;
}

输出

Float: 3.14 -> Int: 3

static_cast<int>(my_float) 表达式将存储在 my_float 中的浮点值转换为整数,并将其存储在 my_int 中。

由于浮点值可以包含小数部分而整数不能,因此此转换会移除小数部分,将 3.14 转换为 3


C++ dynamic_cast

我们主要使用 dynamic_cast 进行 多态 类型转换,尤其是在处理 继承 层级结构时。它通常用于基类 指针 需要转换为派生类指针的场景。

让我们看一个例子。

#include <iostream>
using namespace std;

class Base {
public:
    // base class print function
    virtual void print() {
        cout << "Base class" << endl;
    }
};

class Derived : public Base {
public:
    // derived class print function overriding the base class
    void print() override {
        cout << "Derived class" << endl;
    }
};

int main() {
    // create a Base class pointer 
    // pointing to a Derived object
    Base *base_ptr = new Derived();
    
    // use dynamic_cast to cast the 
    // Base pointer to a Derived pointer
    Derived *derived_ptr = dynamic_cast<Derived*>(base_ptr);
    
    // call the print function through the derived pointer
    if (derived_ptr) {
        derived_ptr->print();
    }

    // delete the dynamically allocated object
    delete base_ptr;

    return 0;
}

输出

Derived class

在此示例中,

  • 我们定义了一个基类 Base 和一个派生类 Derived,其中 Derived 继承自 Base
  • main() 中,我们创建了一个类型为 Base* 的指针 base_ptr,它指向一个 Derived 对象。
  • 然后,我们使用 dynamic_castbase_ptr 转换为 Derived* 指针,并将其赋给 derived_ptr
  • 最后,我们通过 derived_ptr 调用 print() 函数,这意味着在进行动态转换后,我们可以通过 Base 类指针访问 Derived 类的函数。

注意:如果基类指针未指向派生类对象,dynamic_cast 将返回 nullptr


C++ const_cast

我们使用 const_cast 来移除 常量 限定符 变量

一个我们可以使用 const_cast 的常见场景是处理第三方库,这些库有接受非 const 指针作为参数的 函数,但我们需要传入 const 数据。

让我们看一个例子。

#include <iostream>
using namespace std;

// function that takes a non-const pointer
void modify_data(int* data) {
    // modify the data
    *data *= 2;
}

int main() {
    int x = 10;
    
    // a const pointer for variable x
    const int* ptr = &x;

    // use const_cast to 
    // remove const qualifier and allow modification
    int* mutable_ptr = const_cast<int*>(ptr);

    // call the function
    modify_data(mutable_ptr);

    // value is modified successfully
    cout << "Modified value: " << x << endl;

    return 0;
}

输出

Modified value: 20

在此示例中,我们使用 const_cast 表达式来移除指针的 const 限定符,以便将其传递给接受非 const 指针作为参数的函数。

这里,

  • modify_data(int* data):一个接受非 const 指针作为参数的函数。
  • ptr:一个我们需要传递给 modify_data 的 const 指针。
  • const_cast<int*>(ptr):将 ptr 强制转换为非 const 指针,并将其赋给 mutable_ptr

C++ reinterpret_cast

reinterpret_cast 用于将一种指针类型转换为另一种指针类型,或者将一种引用类型转换为另一种引用类型。

static_cast 不同,reinterpret_cast 实际上并不转换数据类型,而是在编译时将一种指针类型重新解释为另一种。

让我们看一个例子。

#include <iostream>
using namespace std;

int main() {
    // create an integer variable
    int x = 67;

    // pointer to an integer
    int* ptr_to_int = &x;

    // reinterpret the pointer to an integer 
    // as a pointer to char
    char* ptr_to_char = reinterpret_cast<char*>(ptr_to_int);

    // dereference the double pointer
    // originally holding an integer as if it contains a double
    cout << "Dereferencing ptr_to_char: " << *ptr_to_char << endl;

    return 0;
}

输出

Dereferencing ptr_to_char: C

在这里,我们使用 reinterpret_cast 将原始指向整数的指针 ptr_to_int 重新解释为指向字符的指针。

这意味着 ptr_to_int 指向的内存位置仍然保存着一个整数值。但它将被视为一个字符。

警告reinterpret_cast 几乎允许任何指针或整数类型之间的转换,而无需进行任何类型安全检查。这可能导致未定义的行为。

因此,应谨慎使用 reinterpret_cast

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战