C++类型转换总结

一、隐式转换
这样的转换也可以叫做隐式转换,类似 小的类型转为大的类型int i = 10; double j = i;此时隐式将Int类型转换成了double类型。

二、显式转换

double j  = 10.0;
int i = int(j);

三、static_cast关键字(编译时类型检查)
用法:static_cast<type_id>(expression),改运算符把expression转换为type_id类型,没有运行时类型检查。
它主要有如下几种用法:

(1)用于基本数据类型之间的转换,如把int转换为char,把int转换成enum,但这种转换的安全性需要开发者自己保证(这可以理解为保证数据的精度,即程序员能不能保证自己想要的程序安全),如在把int转换为char时,如果char没有足够的比特位来存放int的值(int>127或int<-127时),那么static_cast所做的只是简单的截断,及简单地把int的低8位复制到char的8位中,并直接抛弃高位。
(2)把空指针转换成目标类型的空指针
(3)把任何类型的表达式类型转换成void类型
(4)用于类层次结构中父类和子类之间指针和引用的转换

四、dynamic_cast关键字(运行时类型检查)
dynamic_cast主要用于类层次结构父类和子类之间的指针以及引用间的转换,由于有运行时类型检查,保证了下行转换的安全性(转换正确返回正确指针,返回错误则返回NULL)。

类层次的转换包含两种:
(1)上行转换:子类->父类
(2)下行转换:父类->子类

//上行转换
class A
{
virtual void fun(){};
}
calss B:public A
{
}
int main()
{
B * pB = new B;
A * pA = dynamic_cast<A *>(pB);//ok 子类 -> 父类
}
对于上行转换,static_castdynamic_cast效果一样,都安全;
//下行转换
class Base
{
virtual void fun(){};
}
calss Base:public Derived
{
}
int main()
{
	Base* pB1 = new Dervied;//pB1指向派生类
	Base* pB2 = new Base;//pB2指向基类
	Dervied* pD1 = dynamic_cast<Dervied*>(pB1);//Ok
	Dervied* pD2 = dynamic_cast<Dervied*>(pB2);//指向父类的指针转换 结果为NULL 此处转换不成功
}

对于下行转换:你必须确定要转换的数据确实是目标类型的数据,即需要注意:要转换的父类指针是否真的指向子类对象,如果是,static_castdynamic_cast都能成功;如果不是static_cast能返回,但是不安全,可能会出现访问越界错误,而dynamic_cast在运行时类型检查过程中,判定该过程不能转换,返回NULL
//转换为"void *"
class A
    {
    public:
         virtual void f(){}
    };
    class B
    {
    public:
         virtual void f(){}
    };
    int main()
    {
         A *pA = new A;
         B *pB = new B;
         void *pV = dynamic_cast<void *>(pA); 
         pV = dynamic_cast<void *>(pB); 
    }
    但是,在类A和类B中必须包含虚函数,为什么呢?因为类中存在虚函数,就说明它有想让基类指针或引用指向派生类对象的情况,此时转换才有意义;由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。
//陷阱
class A
{
     virtual void Func() = 0;
};
class B : public A
{
     void Func(){};
};
class C : public A
{
     void Func(){};
};
class D : public B, public C
{
     void Func(){}
};
int main()
{
     D *pD = new D;
     A *pA = dynamic_cast<A *>(pD);
}
 如果进行上面的直接转,你将会得到一个NULL的pA指针;这是因为,B和C都继承了A,并且都实现了虚函数Func,导致在进行转换时,无法进行抉择应该向哪个A进行转换。
 
正确的做法是:
int main()
{
     D *pD = new D;
     B *pB = dynamic_cast<B *>(pD);
     A *pA = dynamic_cast<A *>(pB);
}

五、const_cast转换格式:const_cast (expression)
const_cast用来将类型的const、volatile和__unaligned属性移除。常量指针被转换成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然引用原来的对象。

#include <iostream>
using namespace std;
class CA
    {
    public:
         CA():m_iA(10){}
           int m_iA;
    };
    int main()
    {
         const CA *pA = new CA;
         // pA->m_iA = 100; // Error
         CA *pB = const_cast<CA *>(pA);
         pB->m_iA = 100;
         // Now the pA and the pB points to the same object
         cout<<pA->m_iA<<endl;
         cout<<pB->m_iA<<endl;
         const CA &a = *pA;
         // a.m_iA = 200; // Error
         CA &b = const_cast<CA &>(a);
         b.m_iA = 200;
         // Now the a and the b reference to the same object
          cout<<b.m_iA<<endl;
         cout<<a.m_iA<<endl;
    }
注:你不能直接对非指针和非引用的变量使用const_cast操作符去直接移除它的constvolatile和__unaligned属性。

六、reinterpret_cast的转换格式:reinterpret_cast (expression)

允许将任何指针类型转换为其它的指针类型;听起来很强大,但是也很不靠谱。

它主要用于将一种数据类型从一种类型转换为另一种类型。

它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针,在实际开发中,先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原来的指针值;

特别是开辟了系统全局的内存空间,需要在多个应用程序之间使用时,需要彼此共享,传递这个内存空间的指针时,就可以将指针转换成整数值,得到以后,再将整数值转换成指针,进行对应的操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒德久远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值