C++风格的强制类型转换
本文最后更新于 263 天前,其中的信息可能已经有所发展或是发生改变。

一般常用的是C语言风格的强制类型转换(type) expression,这种转换虽然简便,但很是粗糙,无法区分各种细致的转换(比如父类与基类之间的转换,const和非const之间的转换等),并且可能会带来一些难以察觉的问题。

C++为此推出了四种强制类型转换(static_castconst_castdynamic_castreinterpret_cast),但很少有人会使用它们,甚至对此知之甚少。

1. static_cast

与C语言的强制类型转换风格类似,有着相似的含义和功能,一般我们用C语言强制类型转换时都是用此含义,所以以后需要用C语言风格的强制类型转换时可以用static_cast来做,也更能表达清楚代码作用,当然其也有着与C语言风格强制类型转换相同的限制。

写法:static_cast<type>(expression)

注意事项:

  1. 其限制于基本类型间的数据类型转换
  2. 不能去除const属性或volatile属性,const_cast可以
  3. 不能直接进行普通变量、指针与引用之间的转换
  4. 其换类型检查非常严格,不同类型的指针不能直接转换,除非使用void*作为中间参数
  5. 其可以进行类继承体系中向上转换,但最好不要用,用dynamic_cast更好,其不能用于向下转换
  6. 有些时候隐式转换(也是一种C语言风格的强制转换)能够成功,但能用static_cast就要学着用它

示例:

void main() {
        char char1 = 'a';
        float float1 = char1; // 隐式转换成功,但不建议用
        float float2 = static_cast<float>(char1); // 成功
        double double1 = 0.01;
        float float3 = static_cast<float>(double1); // 成功

        int intPtr = 1;
        float* floatPtr1 = &intPtr; // int*与float*之间隐式转换失败
        float* floatPtr2 = static_cast<float*>(&intPtr); // 失败

        void* voidPtr = &intPtr; // 任何指针都可以隐式转换为void*
        void* voidPtr1 =static_cast<void*>(&intPtr); // 成功
        float* float_ptr3 = voidPtr; // void*与float*之间隐式转换失败
        float* float_ptr4 = static_cast<float*>(voidPtr);  //成功
}

2. const_cast

专门用于去除const属性或volatile属性。

写法:const_cast<type>(expression)

注意事项:

  1. 其作用于同类型变量之间,只能有const或volatile的区别,不支持不同类型指针或引用之间的转换,比如说float转换成int是不允许的,转换前后的类型必须相同

示例:

/// 改变函数对变量操作规则
void function(const int& a){
    int& b = const_cast<int&> a; // 同为int&,是同类型
    b = a + 10;
}

void main(){
    int c = 5;
    function(c);
    std::cout << c; // c的值变为了15
}

3. dynamic_cast

用于继承体系中类的转换,一般更多用于做向下或横向安全转换,即把指向父类的指针转换为指向子类父类的兄弟类的指针(或引用),但需要满足一定条件,见注意事项4。

写法:dynamic_cast<type>(expression)

注意事项:

  1. 其是在运行时处理的。(其他三种类型转换都是在编译时完成的)

  2. 其只能对指针或引用进行强制转换

  3. 其可以任意进行向上转换,即把指向子类的指针转换为父类的指针(或引用)

  4. 其对于转换的类具有多态性时,可以进行向下或横向转换,即把指向父类的指针转换为指向子类父类的兄弟类的指针(或引用)

    让类具有多态性即需要类有虚函数或者续继承的类

  5. 转换失败会返回空指针

示例:

class A {...}
class B {
    virtual void test() {...}
    ...
}

class C : public A {...} // C为A的子类,不具有多态性
class D : public B { // D为B的子类,具有多态性
    virtual void test() {...}
    ...
}

void main(){
    /// 1
    C* c;
    A* a = dynamic_cast<A*>(c); // 成功,向上转换无特殊要求

    /// 2
    A* a;
    C* c = dynamic_cast<C*>(a); // 失败,向下转换需要转换类C具有多态性

    /// 3
    B* b;
    D* d = dynamic_cast<D*>(B); // 成功,类D具有多态性,可以向下转换
}

4. reinterpret_cast

用于将一种对象类型转换为另一种,不管它们是否相关,所以说它是C++中最接近于C风格强制类型转换的一个关键字。但一般用于在函数指针之间进行类型转换

写法:reinterpret_cast<type>(expression)

注意事项:

  1. 其可以进行任意变量类型转换,包括普通变量、指针与引用之间,比如:float与double*之间
  2. 其转换结果常常是由编译器的实现所定义的,所以要注意不同编译器可能会造成不同转换结果,也就导致了其代码移植的局限性(所以很少有人经常使用这个类型转换)。
暂无评论

发送评论 编辑评论


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