C++之继承

    • C++之继承
      • 1 公有继承
      • 2 私有继承
      • 3 保护继承
      • 4 派生类的构造函数与析构函数
        • 4.1 派生类的构造函数
        • 4.2 派生类构造函数的特殊形式
        • 4.3 派生类的析构函数
      • 5 多重继承
        • 5.1 多重继承的二义性问题

C++之继承

一个新类从已有类那里获得其已有特性,这种现象称为继承。新类叫做派生类或子类,原来的已有类叫做基类或父类。值得注意的是派生类和基类永远是相对而言的。

1 公有继承

采用共有继承方式时,基类的公用成员和保护成员在派生类中仍然保持原来的属性不变,而基类中的私有成员在派生中并没有成为派生类中的私有成员,它仍只然是基类的私有成员,只有基类的成员函数可以引用它,而不能被派生类的成员函数所引用。

公用基类成员在派生类中的属性见下图所示:
C++之继承_第1张图片

2 私有继承

采用私有继承方式时,私有基类的公有成员和保护成员在派生类中成了派生类的私有成员,即只能在派生类中访问它们而不能在派生类外部访问它们。至于私有基类的私有成员,派生类不可访问。

私有基类成员在派生类中的属性如下图所示:
C++之继承_第2张图片

3 保护继承

采用保护继承方式时,保护基类中的公有成员和保护成员和保护成员都成了派生类的保护成员,即他们只能被派生类和派生类的派生类访问而不能在其他位置访问(基类除外,因为这些成员本来就是基类的成员);基类的私有成员仍为基类私有。

保护基类成员在派生类中的属性如下图所示:
C++之继承_第3张图片

4 派生类的构造函数与析构函数

派生类不能继承基类的构造函数和析构函数

4.1 派生类的构造函数

定义派生类构造函数的一般形式为:

派生类构造函数名(总参数表)
    :基类构造函数名(参数表),  //此处的参数表是实参
    子对象名(参数表)           //此处的参数表是实参
{派生类中的新增数据成员初始化语句}

执行派生类构造函数的顺序是:
1. 调用基类构造函数,初始化基类的数据成员;
2. 调用子对象构造函数,初始化子对象的数据成员;
3. 再执行派生类构造函数本身,初始化派生类的数据成员。

这里出现了一个名词:子对象。什么是子对象呢?
实际上,类中的数据成员还可以包含类的对象,例如在声明一个类时包含这样的数据成员Student s1; //Student是已声明类,s1是Student类的对象。 这时,s1就是类的内嵌对象,称为子对象,即对象的对象。

4.2 派生类构造函数的特殊形式

一、当不需要对于派生类新增成员进行任何的初始化操作时,派生类构造函数的函数体为空,即构造函数是空函数。此时派生类构造函数中只有调用基类构造函数和子对象的构造函数。派生类构造函数中的参数个数等于基类构造函数参数个数和子对象的参数个数之和。派生类构造函数的参数仅用于完成对基类成员和子对象成员的初始化。

二、当基类中不需要用参数完成初始化时,那么在定义派生类构造函数时可以不写基类构造函数。如果基类和子对象的声明类中都没有定义带参数的构造函数,而且也不需对派生类自己的数据成员进程初始化,那么就可以不必显示地定义派生类的构造函数。在建立派生类的构造函数时,系统会自动调用系统提供的派生类的默认构造函数,并在执行派生类的构造函数过程中,调用基类的默认构造函数和子对象类型默认构造函数。

三、如果在基类或者子对象类型的声明中定义了带参数的构造函数,那么就必须显式地定义出派生类的构造函,并且在派生构造函数中写出基类或者子对象类型的构造函数及其参数表。

四、如果在基类中既定义了不带参数的构造函数也定义了带参数的构造函数,那么在定义派生类的构造函数时既可以写出基类的构造函数及其参数,也可以不写出基类的构造函数。至于在执行派生类的构造函数时到底调用哪个基类的构造函数,则取决于派生类的内容。

4.3 派生类的析构函数

在派生类中可以根据需要定义自己的析构函数,用来对派生类中所有新增成员进行清理工作。基类的析构函数仍然只负责对基类成员进程清理工作。在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理工作。

5 多重继承

派生类继承时,从多个基类中继承来,叫做多重继承。

5.1 多重继承的二义性问题

一、在多个基类中有同名的成员时,对于继承这些基类的派生类而言,就继承出若干个同名的成员。那么到底是哪个是哪个呢?此时就出现了二义性问题。

二、若有基类A,A有成员a。此时有两个派生类B和C,都继承了A。然后再有个派生类D,这个D继承了B和C。那么对于派生类D而言,就会继承得来两个成员a,此时也出现了二义性问题。

怎么解决呢?
有一个办法,将二义的成员前面加上类限定符即可。即用基类名来指明到底哪个成员时哪个基类的。
另外一个办法,就是用关键字virtual,具体内容将在下一篇博客中讲到。

你可能感兴趣的:(C/C++,C++,继承,二义性)