了解C++中的四种 Cast
本文最后更新于327 天前,其中的信息可能已经过时,如有错误请联系作者

了解C++中的四种 Cast

static_cast

static_cast 是 C++ 中用于执行显式类型转换的操作符,它允许你在编译时进行类型转换,而不是在运行时。static_cast 通常用于执行安全的类型转换,比如基本数据类型的转换、类层次结构中的向上转换(将派生类指针或引用转换为基类指针或引用),以及向下转换(在你知道类型确实匹配的情况下,将基类指针或引用转换为派生类指针或引用)。

  1. 基本数据类型转换:
int a = 10;
char c = static_cast<char>(a); // int 到 char 的转换
  1. 类层次结构中的向上转换(安全):
class Base {};
class Derived : public Base {};

Derived* d = new Derived();
Base* b = static_cast<Base*>(d); // Derived* 到 Base* 的转换
  1. 类层次结构中的向下转换(不安全,除非你知道确实类型匹配):
Base* b = new Derived();
Derived* d = static_cast<Derived*>(b); // Base* 到 Derived* 的转换
// 只有当你确信 b 指向的是 Derived 对象时,这种向下转换才是安全的
//如果你需要确保安全性,应该使用 dynamic_cast,它会检查转换是否合法,并在不合法时返回 nullptr(对于指针)或抛出 std::bad_cast 异常(对于引用)。
  1. void* 转换为具体类型:
void* ptr = ...;
int* intPtr = static_cast<int*>(ptr); // void* 到 int* 的转换

使用 static_cast 时需要注意以下几点:

  • static_cast 不会进行运行时类型检查,因此如果转换不正确,可能会导致未定义行为。
  • static_cast 不能用于删除 constvolatile__unaligned 修饰符,如果要去除这些修饰符,应该使用 const_cast
  • static_cast 不能用于将非类类型转换为类类型,这种转换通常是不安全的。

dynamic_cast

dynamic_cast 是 C++ 中用于在类层次结构中进行安全向下转换(downcasting)的操作符。它允许你将基类指针或引用转换为派生类指针或引用,并且在转换过程中进行运行时类型检查(RTTI)。如果转换是不合法的,即基类指针实际上并不指向派生类对象,那么 dynamic_cast 会返回 nullptr(对于指针)或抛出 std::bad_cast 异常(对于引用)。

RTTI

RTTI(Run-Time Type Information,运行时类型信息)是 C++ 中的一种机制,它允许程序在运行时获取对象的类型信息。RTTI 主要用于两个方面:类型识别和类型转换。

  1. 类型识别:RTTI 允许程序检查一个对象的具体类型,这是通过 typeid 操作符实现的。typeid 返回一个 type_info 对象,该对象包含有关类型的详细信息,如类型名称。
  2. 类型转换:RTTI 允许程序在运行时安全地转换对象类型,这是通过 dynamic_cast 操作符实现的。dynamic_cast 可以将对象指针或引用安全地转换为目标类型的指针或引用,如果在转换过程中类型不匹配,对于指针返回 nullptr,对于引用抛出 std::bad_cast 异常。

在RTTI的实现中,RTTICompleteObjectLocator是一个重要的结构体,它包含了几个关键成员:

  1. typeinfo:这是一个包含类型名和父类类型名的结构体,通过typeid函数可以获取对象的typeinfo,从而得到对象的类型信息。
  2. class descriptor:这是一个描述继承关系和信息的结构体。它记录了基类的个数、基类的数组、以及该类是否使用了多继承或虚继承。
  3. offset:这是虚函数指针相对于类头部的偏移量。它可以用来优化动态类型转换(如dynamic_cast)的速度,因为当将基类的指针转换为派生类的指针时,可以直接通过this指针加上这个偏移量来找到正确的位置。

RTTI的使用场景是,在代码运行时并不知道一个指针指向的是子类还是基类对象,就需要通过RTTI得到其信息,比如typeid和dynamic_cast。RTTI存在于每个虚函数表首地址往上的四个字节,所以父类至少要有一个虚函数,否则无法识别正确类型。

以下是一些需要注意的点:

  1. dynamic_cast 仅适用于包含至少一个虚函数的类层次结构,因为它是通过虚函数表来实现运行时类型检查的。
  2. dynamic_cast 用于向下转换时比 static_cast 安全,因为它会检查转换的合法性。
  3. dynamic_cast 的性能成本比 static_cast 高,因为它需要在运行时进行类型检查。
  4. dynamic_cast 可以用于交叉转换,即在不同继承层次的派生类之间进行转换。
  5. 有个值得注意的点,菱形继承和侧向转换时,dynamic_cast可能会因二义性造成转换失败。
class Base {
public:
    virtual void f() {}
};

class Derived : public Base {
public:
    void f() override {}
};

Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b); // 安全的向下转换
if (d) {
    // 转换成功,d 指向 Derived 对象
} else {
    // 转换失败,b 不指向 Derived 对象
}

const_cast

const_cast 是 C++ 中用于去除 const 特性的类型转换操作符。它允许你将 const 对象的指针或引用转换为非 const 对象的指针或引用,从而使得原本不可修改的对象变得可修改。这种转换是在编译时进行的,但它不会改变对象本身的 const 性质,只是让编译器允许你通过指针或引用修改对象。

只能修改常量指针,不能修改指针常量。

  1. const_cast 仅用于去除 const 或 volatile 特性,不能用于其他类型的转换。
  2. const_cast 只适用于指针或引用,不能直接应用于对象。
  3. 使用 const_cast 去除 const 特性是危险的,因为它可能会导致对 const 对象的意外修改,从而破坏程序的不变性和安全性。
class MyClass {
public:
    void modify() { /* ... */ }
};


int main()
{
    const MyClass obj;
    MyClass* nonConstPtr = const_cast<MyClass*>(&obj);
    nonConstPtr->modify(); // 现在 可以调用非 const 成员函数了

    // 使用 const_cast 去除 volatile 特性
    volatile int vi = 1;
    int* nonVolatilePtr = const_cast<int*>(&vi);
    *nonVolatilePtr = 2; // 现在 可以修改 volatile 变量了
}

reinterpret_cast

reinterpret_cast 是 C++ 中用于执行非类型安全的低级类型转换的操作符。它允许你将一个指针、引用或数据类型的值转换为另一个指针、引用或数据类型的值,除了无法去掉const属性,可以随便转换,但不会进行任何类型检查或运行时类型信息(RTTI)检查。

int* ptr = new int(10);
// 将 int 指针转换为 int 类型的整数
int intValue = reinterpret_cast<int>(ptr);

// 将 int 类型的整数转换回 int 指针
int* newPtr = reinterpret_cast<int*>(intValue);

// 将 int 指针转换为 void 指针
void* voidPtr = reinterpret_cast<void*>(ptr);

// 将 void 指针转换回 int 指针
int* anotherPtr = reinterpret_cast<int*>(voidPtr);

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇