本节讨论不同的继承方式造成的不同内存布局。 2.1 C结构(struct) 由于C++基于C,所以C++也“基本上”兼容C。特别地,C++规范在“结构”上使用了和C相同的,简单的内存布局原则:成员变量按其被声明的顺序排列,按具体实现所规定的对齐原则在内存地址上对齐。所有的C/C++厂商都保证他们的C/C++编译器对于有效的C结构采...
C对象有两部分组成,红色区域是继承自B的部分,蓝色区域是自身特有的。这样一来,红色部分全然能够当成是一个B类对象。 2 利用结构体实现继承的两种方法 2.1 父类对象作为子类的成员 理解了继承的内存布局原理之后,用C来实现继承就很easy了。最easy想到的方法例如以下: structB{intx;inty;intz; };structC{structBo...
/* 基类 */typedefstruct_animal_tanimal_t;/* 动物类 */struct_animal_t{unsignedintstamina;/* 体力 */};/* 派生类 */typedefstruct_human_thuman_t;/* 人类 */struct_human_t{animal_tancestor;/* 继承基类 */unsignedintintelligence;/* 智力 */}; 内存布局示意图 在派生类中的构造函数需要调用基...
类C的实例有如下的内存布局,基类指针pB和父类指针pA依然都指向同一个位置,只是这个位置不再是变量c所在的位置,而是虚表指针所在的位置。 从上面图中我们还可以看到:「编译器很巧妙地把类B的虚表指针和类A的虚表指针进行了合并,类B的实例中只有一个虚表指针。」 还有一种情况就是基类没有虚表但是继承类有,如下面...
Base内存布局 可以看到,对一个C++对象来说,它的内存布局仅有虚表指针和非静态成员,而其他的静态成员,成员函数(静态,非静态),虚表等都是布局在类上的。 当然,这是没有考虑继承的情况。继承情况下会更复杂一些。可以参考(http://www.cnblogs.com/QG-whz/p/4909359.html) ...
//向该类所继承的父类对象 Class _Nullable super_class OBJC2_UNAVAILABLE; const char * _Nonnull name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; //成员变量列表
我们来看一下 Rectangle 的继承关系和内存布局: 因为有这样的内存布局,所以你可以很安全的传一个指向 Rectangle 对象的指针到一个期望传入 Shape 对象的指针的函数中,就是一个函数的参数是 “Shape *”,你可以传入 “Rectangle *”,并且这是非常安全的。这样的话,基类的所有属性和方法都可以被继承类继承!
虚拟内存布局: 虚拟内存布局分为内核空间、栈、堆、数据段、代码段和一个不允许访问的空间(相当于一堵墙)。 一个用户进程可以访问的内存区域介于 0x0804 8000 到0xc0000000 之间,这个“广袤”的区域又被分成了几个部分,分别用来存放进程的代码和数据。
分析C++类对象在下面情形中的内存布局: 单继承:子类单一继承自父类,分析了子类重写父类虚函数、子类定义了新的虚函数情况下子类对象内存布局。多继承:子类继承于多个父类,分析了子类重写父类虚函数、子类定义了新的虚函数情况下子类对象内存布局,同时分析了非虚继承下的菱形继承。虚继承:分析了单一继承下的虚继承...