派生类与基类之间的关系(is-a)

@1 派生类会继承基类的数据成员和部分方法成员,并将其加入派生类的相应区域(public、private、protected,取决于才去的继承方式)。之所以是部分方法成员,是因为有一些特殊的函数不会被继承:构造函数、析构函数、赋值运算符函数等。public、private、protected区域的划分只是对可见性的一种描述,并不是真正实现上按这种方式进行划分。基类就像是派生类对象内嵌的一个对象。通过这种内嵌的方式来实现继承。(自己的理解)

@2 派生类对象被创建时,必须先创建基类对象。正如前述,基类对象可以理解为是派生类对象的一个内嵌对象,以此实现继承。因此,在派生类内需要对继承而来的基类的成员进行访问时,必然需要先对内嵌的基类对象进行创建。创建基类对象的方式可以采用成员初始化列表语法进行显式调用基类的构造函数,否则将会自动调用基类的默认构造函数进行基类对象的创建。

不会被继承的特殊类方法(函数)

构造函数、析构函数、赋值运输符函数。这三类方法(函数)是不会从基类中被继承到派生类中的。所以如果有必要,例如在派生类对象采用new分配动态内存时,需要在派生类中添加属于派生类的构造、析构、赋值运算符函数等等(为了解决deep copy问题)。

总结:派生类对象所拥有的类成员方法(函数)

@1 从基类继承过来的未被重新定义的方法(函数)

@2 在派生类中对基类方法(函数)重新定义后的方法(函数)

@3 在派生类中新添加的派生类方法(函数)

-通过派生类对象对从基类继承过来的类方法进行调用

首先判断是否在派生类中有对该基类方法进行重新定义,如果有,说明该类方法的基类版本已经被在派生类中重新定义的版本所覆盖了,也就是被隐藏了。因此将调用该基类方法在派生类中重新定义的版本;如果没有重新定义,则会使用从基类继承得到的属于派生类的基类版本的类方法。

-通过派生类对象对未从基类继承的特殊类方法(函数)进行调用

如果在派生类中没有定义这三种特殊方法(函数)

  • 构造函数:会自动调用基类构造函数
  • 复制构造函数(特殊的构造函数):会自动生成默认复制构造函数,并且采用逐成员复制的方式进行复制。在逐成员对象复制时,会调用各个成员对象的复制构造函数完成复制。特别的,在基类对象复制时,将调用基类的复制构造函数。
  • 析构函数:会生成默认的析构函数,并且先对派生类对象调用析构函数,再自动调用内嵌的基类对象的析构函数
  • 赋值运算符函数:同复制构造函数,会自动调用基类的赋值运算符函数。

如果在派生类中定义了这三种特殊函数,则在通过派生类对象对其进行调用时,将调用派生类中定义的函数。

如果在派生类没有使用new进行动态内存分配时,无需在派生类中定义以上三种特殊的函数。但是如果在派生类中使用了new进行动态内存的分配,则必须在派生类中显式定义以上三种特殊的函数。同样是为了解决deep copy的问题。