class Animal
public:
int m_age;
class Sheep :virtual public Animal {};
class Tuo :virtual public Animal {};
class SheepTuo :public Sheep, public Tuo {};
vbptr是虚指针,由于Sheep和Tuo都是虚继承的方式继承Animal的,所以这俩类只是各多了一个虚指针,指向对应的vbtable,vbtable是虚表,Sheep和Tuo的虚指针会查虚表,记录偏移量,比如Sheep的虚指针地址偏移量为0,Sheep的虚表里面的记录的偏移量是8,0+8就是Animal的m_age的地址偏移量;同理对于Tuo来说4+4也是Animal的m_age的地址偏移量。这样的话,SheepTuo就只包含一个m_age。那么如果把SheepTuo继承Sheep和Tuo的方式都改为虚继承呢?那么SheepTuo自己也会有一个虚指针,这个虚指针指向一个虚表,虚表里放着从Sheep和Tuo还有Animal继承过来的内容。此时仍旧只有一份Animal的m_age,如下图:
在继承中与其他成员不同,构造方法不能被子类继承。在创建子类对象时,为了初始化从父类继承来的成员,需要调用父类的构造方法。if(子类没有自定义构造函数){
if(基类没有自定义构造函数){
用子类定义对象时,先自动调用基类的默认构造函数,再调子类的默认构造函数。
} else if(基类有自定义无参构造函数){
构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。
如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。
构造原则如下:
1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法。
2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。
3. 在创建子
文章目录一、继承二、重写与父类子类区别1、使用继承2、子类访问父类成员3、不能继承的父类成员4、访问修饰符5、继承后的初始化顺序6、子类的特性信息三、多种封装关键字对比封装的关键字四、抽象类与抽象方法
一、继承
接下来,我们按照小狗的方式,新建马和企鹅的类。但是如果我们每一种动物都重写一遍,工作量很大。因为每种动物都有一些节本的共性,因此,我们这里可以采用一种办法,就是继承。
我们先新建一个Pet类,然后将共性的信息放到Pet类中。
package com.icss.bk.biz;
public clas
构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。
如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。
构造原则如下: