2024-5-3学习笔记 继承关系拓展

一.继承与友元

友元类不能继承,也就是说基类友元不能访问子类私有和保护成员。简单的理解就是,爸爸的朋友不是儿子的朋友。

二.继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例 。

利用这个特性,我们就可以统计一个类创建了多少个对象。

class Person
{
public :
 Person () {++ _count ;}
protected :
 string _name ; // 姓名
public :
 static int _count; // 统计人的个数。
};
int Person :: _count = 0;
class Student : public Person
{
protected :
 int _stuNum ; // 学号
};
class Graduate : public Student
{
protected :
 string _seminarCourse ; // 研究科目
};
void TestPerson()
{
 Student s1 ;
 Student s2 ;
 Student s3 ;
 Graduate s4 ;
 cout <<" 人数 :"<< Person ::_count << endl;
 Student ::_count = 0;
 cout <<" 人数 :"<< Person ::_count << endl;
}

三.复杂的菱形继承及菱形虚拟继承

我们之前所讲的知识,都是建立在单继承的基础上,C++除了有单继承,还有多继承。

单继承:一个子类只有一个直接父类时称这个继承关系为单继承

多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承

下面要介绍一种特殊情况:

菱形继承:菱形继承是多继承的一种特殊情况。

 一个类继承了两个类,而两个类又继承了同一个父类,逻辑上像一个菱形,就叫菱形继承。

菱形继承的问题

来看下图

可以看到,在派生类构造时,由于自己继承的父类都具有一个共同的父类,在构造时就会构造两个相同的父类的父类,导致数据冗余。

此外,还会导致数据二义性的问题,派生类如果要调用父类的符类的成员时会定义不清晰。

class Person
{
public :
 string _name ; // 姓名
};
class Student : public Person
{
protected :
 int _num ; //学号
};
class Teacher : public Person

{
protected :
 int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
 string _majorCourse ; // 主修课程
};
void Test ()
{
 // 这样会有二义性无法明确知道访问的是哪一个
 Assistant a ;
a._name = "peter";
// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
 a.Student::_name = "xxx";
 a.Teacher::_name = "yyy";
}

解决方法

利用虚拟继承

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和 Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地 方去使用。

class Person
{
public :
 string _name ; // 姓名
};
class Student : virtual public Person
{
protected :
 int _num ; //学号
};
class Teacher : virtual public Person
{
protected :
 int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
 string _majorCourse ; // 主修课程
};
void Test ()
{
 Assistant a ;
 a._name = "peter";
}

相关推荐

  1. C#学习笔记_继承

    2024-05-03 10:56:07       47 阅读
  2. 2024/5/3学习笔记:派生类的默认成员函数

    2024-05-03 10:56:07       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-03 10:56:07       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-03 10:56:07       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-03 10:56:07       82 阅读
  4. Python语言-面向对象

    2024-05-03 10:56:07       91 阅读

热门阅读

  1. 03.磁盘管理与维护命令

    2024-05-03 10:56:07       26 阅读
  2. CAPM模型(Capital Asset Pricing Model)注意事项

    2024-05-03 10:56:07       32 阅读
  3. C++完美转发

    2024-05-03 10:56:07       28 阅读
  4. npm许可证检查

    2024-05-03 10:56:07       28 阅读
  5. C++@vscode配置C++开发环境常见问题和实践经验

    2024-05-03 10:56:07       38 阅读
  6. 什么是dreamfusion

    2024-05-03 10:56:07       28 阅读