C++之强制类型转换原理

不管是哪种编程语言,都会涉及到数据类型转换。强制类型转换是将操作数的类型转换成所需要的类型。强制类型转换到底是如何实现的?请先看下面一个简单数据类型的转换:

一、简单数据类型的强制类型转换

char b = 'a';
int  num = (int)b;

上面是一个很简单的由char转为int数据,我们得到num为97。那么这个类型转换的原理是怎么样的呢?我们一起来看一下两个数据类型在内存中的存储模型:
   
我们看到char占据1个字节而int占据4个字节;能不能强制类型转换的关键在于两者的模型能不能互相 在一块。就拿char和int类型的内存模型来模拟,char的模型可以扣在int的内存模型之中,而int的内存模型也可以扣在char的模型上,所以两者在内存中可以发现模型的相互转换,这就形成了数据类型的转换。这就是强制类型转换原理的形象化表达。
我们可以发现,把1个char的内存扣在1个int类型的内存模型时,不能完全覆盖,导致还有3个字节没有利用到;而把int类型的4个字节的内存模型扣在char型上时,由于char只占据一个字节,导致int的多余三个无法扣上去,这就会被内存管理器给舍弃,这就是 精度丢失 的原因。所以吧int型转换成char型,编译器会警告精度丢失。

二、对象的强制类型转换

从上面一个例子,我们可以得到在简单数据类型下,两者的内存模型在相互兼容的情况下可以发生强制类型转换,那么请我们联系对象的强制类型转换又是怎么样的呢?
在类的继承过程中,基类可以派生出很多的派生类,我们可以使用基类的对象进行强制类型转换为派生类的对象,但是无法将派生类的对象强制类型转换提升为基类对象,这是为什么呢?
这里小编提出下自己的想法。
基于内存模型的兼容性原理,我们首先明确一点,类的设计相当于内存模型的设计,而基类在派生出派生类的时候,派生类会继承基类然后再创建出属于自己的那部分,我们可以看下面的代码:
class A
{
    public:
         A(int _x):x(_x){};
         void fun1();
         virtual ~A();
         virtual void g1()
    private:
         int x;
}
当基类A派生出派生类B的时候,B会继承基类同时产生新的部分,我们知道派生类的结构是如下:
派生类对象内存模型:      基类对象内存模型:

假设基类的内存模型正如基类部分一样,那么两者的内存模型是兼容的,所以基类可以扣在派生类上,两者基类部分的相关成员变量与成员函数的内存模型都是相同的,所以可以用基类的指针来指向派生类。
但是反过来当把派生类的内存模型扣在基类的内存模型上时,会造成精度损失。在对象方面,精度损失则意味这派生类新创建的成员变量和相关函数无法构造,这会导致派生类无法正常运行,所以编译器禁止派生类去指向基类对象。


以上就是小编对强制类型转换以及对象间基类能够指向派生类而派生类无法指向基类的原因。多提一点关于多态性与虚函数方面的话题,当基类指针指向派生类对象的时候,如果基类中的有非virtual方法时,调用该方法会直接调用基类部分的而不会调用派生类重载的同名方法,因为这是静态编译时就已经确定的;而当调用virtual方法的时候则会动态时确定,所谓的动态时确定就是在构建对象的时候得到虚表指针,重载的虚函数会放在基类的虚函数之前,因此会调用派生类重载的虚函数方法来实现多态性。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值