前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2024-5-3学习笔记 继承关系拓展

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

作者头像
对编程一片赤诚的小吴
发布2024-05-04 09:09:12
920
发布2024-05-04 09:09:12
举报
文章被收录于专栏:热爱编程的证据

一.继承与友元

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

二.继承与静态成员

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

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

代码语言:javascript
复制
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++除了有单继承,还有多继承。

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

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

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

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

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

菱形继承的问题

来看下图

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

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

代码语言:javascript
复制
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时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地 方去使用。

代码语言:javascript
复制
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";
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.继承与友元
  • 二.继承与静态成员
  • 三.复杂的菱形继承及菱形虚拟继承
    • 菱形继承的问题
      • 解决方法
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档