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;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值