C++ 4种类型转换运算符

经常被C++强制类型转换所困扰,所以今天进行系统的总结一下。

C++添加了如下4种类型转换运算符,目的是为了更严格的限制允许的类型转换,使转换过程更加规范。

dynamic_cast

const_cast

static_cast

reinterpret_cast

这样可以根据目的选择一个合适的运算符,并不是使用通用的类型转换。

1、dynamic_cast

语法dynamic_cast < type-name > (expression)

用途:使得能够在类层次结构中进行向上转换(由于Is-a关系(继承),所以这种类型转换时安全的)而不允许其他转换。失败返回0。

实例:

扫描二维码关注公众号,回复: 2934176 查看本文章
class A
{
public:
int m_Test;
virtual void Test(){}
};
class B : public A
{
public:
int m_count;
};
int main()
{
B *b = new B;
A *a = dynamic_cast<A*> (b);
return 0;
}

2、const_cast

语法:const_cast < type-name > (expression)

用途:用于执行只有一种用途的类型转换,即改变值为 const 或 volatile。

 当某一个值在大量使用常量,有时候又是可以修改的,在这种情况下,可以将值声明为const,并在需要修改他的时候,使用const_cast。

实例:

B b;
const B *bb = &b;
B *bbb = const_cast<B*> (bb);

3、static_cast

语法:static_cast < type-name > (expression)

用途:可用于操作 如将指针转换为基类,以及指向派生类的指针。这种转换并不总是安全的。

区别:一般来static_cast,如果要将数字数据类型(如枚举)转换为整数或整数,则可以使用浮点数,并确定转换中涉及的数据类型。static_cast转换并不像转换那样安全dynamic_cast,因为static_cast没有运行时类型检查dynamic_cast一个dynamic_cast含混的指针会失败,而static_cast返回好像没有什么是错的; 这可能是危险的。尽管dynamic_cast转换更安全,但dynamic_cast只能用于指针或引用,而运行时类型检查是一种开销。

实例:

class B {};
class D:public B{};
void f(B * pb,D * pd){
D * pd2 = static_cast <D *>(pb); //不安全,D可以有和不在B中的方法  
 B * pb2 = static_cast <B *>(pd); //安全转换,D总是包含全部B.  
}

4、reinterpret_cast

语法: reinterpret_cast < type-name > (expression)

用途:用于天生危险的类型转换,该运算符的用法比较多,是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。

实例:

int *n= new int ;
double *d=reinterpret_cast<double*> (n);
在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析。
static_cast 和reinterpret_cast的区别主要在于多重继承 ,比如
class A {
public:
        int m_a;
};
class B {
    public:
    int m_b;
};
class C : public A, public B {};
C c;
printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast <B*>(&c));
前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节,这是因为static_cast 计算了父子类指针 转换的偏移量 ,并将之转换到正确的地址(c里面有m_a,m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。
因此, 需要谨慎使用 reinterpret_cast.


猜你喜欢

转载自blog.csdn.net/weixin_40222745/article/details/79210719
今日推荐