C++强制类型转换

C++强制类型转换

void Test()
{
    int i = 1;
    //隐式类型转换
    double d = i;
    printf("%d %.2f\n",i, d);
    int* p = &i;
    //显示类型转换
    int address = (int)p;
    printf("%x, %d\n", p, address);
}
static_cast

static_cast用于非多态类型的转换(静态转换),任何标准转换都可以用它,但是不可以用于两个不相关的类型进行转换。

void Test()
{
    int i = 1;
    double d = static_cast<double>(i);
    printf("%d %.2f\n",i, d);
}
reinterpret_cast

reinterpret_cast用于将一种类型转换为不同的类型。

typedef void (*Func)();

int Dosomething(int i)
{
    cout<<"Dosomething"<<endl;
    return 1;
}

void Test()
{
    Func f = reinterpret_cast<Func>(Dosomething);
    f();
}

reinterpret_cast( )

T 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。

reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。(这句话是C++编程思想中的原话)

reinterpret_cast和static_cast的主要区别在多重继承。例如:

class A
{
    int m_a;
};

class B
{
    int m_b;
};

class C : public A, public B
{};

int main()
{
    C c;
    printf("%p  %p  %p\n", &c, reinterpret_cast<B*>(&c), static_cast<B*>(&c));
    system("pause");
}

上面这段代码中, 前两个输出值相同,第三个偏移了四个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a,m_b,转换为B*指针后指到m_b处),reinterpret_cast却不会做这一层转换。

慎用reinterpret_cast

const_cast

const_cast最常用的属性就是删除变量的const属性,方便赋值。

int main()
{
    volatile const int a = 2;
    //volatile避免值被编译器优化到寄存器
    int* p = const_cast<int*>(&a);
    *p = 3;
    cout<<a<<endl;
    system("pause");
}
dynamic_cast

dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)

  1. dynamic_cast只能用于含有虚类的函数
  2. dynamic_cast会先检查是否能成功转换,能转换则转换,如果不能则返回。
class A
{
public:
    virtual void Func(){}
};

class B : A
{};

void fun(A* pa)
{
    //B* pb1 = static_cast<B*>(pa);
    B* pb2 = dynamic_cast<B*>(pa);
    //cout<<"pb1:"<<pb1<<endl;
    cout<<"pb2:"<<pb2<<endl;
}

int main()
{
    A a;
    B b;
    fun(&a);
    //fun(&b);
    system("pause");
    return 0;
}
explicit关键字

explicit关键字阻止经过转换构造函数进行的隐式转换的发生。

class A
{
    explicit A(int a)
    {
        cout<<"A(int a)"<<endl;
    }

    A(const A& a)
    {
        cout<<"const A& a"<<endl;
    }

private:
    int _a;
};

int main()
{
    A a1(1);
    A tmp(1);
    A a2(tmp);
    A a2 = 1;

}
### C++ 强制类型转换方法及其使用指南 #### 新式转型概述 在C++中,强制类型转换被称为新式转型,区别于C语言中的旧式转型。新式转型提供了四种不同的关键字来执行特定类型的转换操作:`static_cast`、`dynamic_cast`、`const_cast` 和 `reinterpret_cast`[^1]。 #### Static Cast (静态转换) `static_cast` 是一种编译期检查的类型转换机制,适用于基本数据类型间的相互转换以及具有继承关系的对象之间安全的方向上的转换。例如: ```cpp double dValue = 3.14; int iValue = static_cast<int>(dValue); ``` 对于指针或引用来说,当基类和派生类存在单根继承体系时可以实现向下转型(即从基类到派生类),但是这种情况下应该优先考虑使用更安全的方式——`dynamic_cast`。 #### Dynamic Cast (动态转换) `dynamic_cast` 主要用于处理多态对象之间的转换,在运行期间能够判断两个类型间是否存在合法的关系并返回相应结果。如果尝试非法的操作,则会抛出异常或者返回null指针取决于具体场景。这使得它成为最安全但也可能是性能开销最大的选项之一: ```cpp Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); if(derivedPtr != nullptr){ // 成功转换... } else{ // 转换失败... } ``` 此功能特别适合用来验证是否可以从某个已知接口获取更加具体的实例化版本[^3]。 #### Const Cast (常量属性修改) `const_cast` 的作用在于移除变量声明时所附加的 const 或 volatile 属性。虽然有时确实有必要这样做,但在大多数时候应当尽量避免改变原本设计意图下的不可变性约束,因为这可能会引发未定义行为的风险。 ```cpp void someFunction(const int& value){ int* nonConstValue = const_cast<int*>(&value); (*nonConstValue)++; } // 注意上述做法并不推荐除非有充分理由证明其安全性。 ``` #### Reinterpret Cast (重新解释位模式) 最后是 `reinterpret_cast`, 它允许程序员直接操纵底层二进制表示形式来进行几乎任何种类的数据视图变换。然而由于缺乏语义层面的理解和支持,误用该特性极易造成难以调试的问题甚至危及整个系统的稳定性。因此仅限于那些真正需要低级控制的应用场合下谨慎采用,并且通常只会在非常特殊的情况下才会涉及到此类操作[^2][^4]: ```cpp uintptr_t rawAddress = reinterpret_cast<uintptr_t>(&someObject); void* genericPointer = reinterpret_cast<void*>(rawAddress); ``` 综上所述,每种类型转换都有各自适用范围内的最佳实践指导原则,合理选择合适的工具可以帮助开发者写出既高效又可靠的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值