c++继承和派生(个人总结笔记)

c++继承和派生(个人总结笔记)

  • 一、继承和派生
    • 1、C++继承的概念及语法
    • 2、C++继承权限和继承方式
    • 3、C++继承时的名字遮蔽
    • 4、C++派生类构造函数
    • 5、派生类的析构函数
    • 6、C++虚继承和虚基类
    • 7、C++虚继承时的构造函数

一、继承和派生

1、C++继承的概念及语法

  • 继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承类似,例如儿子继承父亲的财产。

  • 继承(Inheritance) 可以理解为一个类从另一个类获取成员变量和成员函数的过程。例如类 B 继承于类 A,那么 B 就拥有 A 的成员变量和成员函数。被继承的类称为父类或基类,继承的类称为子类或派生类。

  • 继承方式包括 public(公有的)、private(私有的)和 protected(受保护的),此项是可选的,如果不写,那么默认为 private。

  • demo语法

class 派生类名:[继承方式] 基类名{
派生类新增加的成员
};

//基类 Pelple
class People{

}
//派生类 Student
class Student: public People{

}

Student 类继承了 People 类的成员成员函数 。这些继承过来的成员,可以通过子类对象访问,就像自己的一样。

2、C++继承权限和继承方式

public、protected、private 指定继承方式
不同的继承方式会影响基类成员在派生类中的访问权限

  1. public继承方式
  • 基类中所有 public 成员在派生类中为 public 属性;
  • 基类中所有 protected 成员在派生类中为 protected 属性;
  • 基类中所有 private 成员在派生类中不能使用。
  1. protected继承方式
  • 基类中的所有 public 成员在派生类中为 protected 属性;
  • 基类中的所有 protected 成员在派生类中为 protected 属性;
  • 基类中的所有 private 成员在派生类中不能使用。
  1. private继承方式
  • 基类中的所有 public 成员在派生类中均为 private 属性;
  • 基类中的所有 protected 成员在派生类中均为 private 属性;
  • 基类中的所有 private 成员在派生类中不能使用。
    c++继承和派生(个人总结笔记)_第1张图片
  • 由于 private 和 protected 继承方式会改变基类成员在派生类中的访问权限,导致继承关系复杂,所以实际开发中我们一般使用 public。
  • 改变访问权限
    using 关键字可以改变基类成员在派生类中的访问权限,例如将 public 改为 private、将 protected 改为 public。

3、C++继承时的名字遮蔽

如果派生类中的成员(包括成员变量和成员函数)和基类中的成员重名,那么就会遮蔽从基类继承过来的成员。所谓遮蔽,就是在派生类中使用该成员(包括在定义派生类时使用,也包括通过派生类对象访问该成员)时,实际上使用的是派生类新增的成员,而不是从基类继承来的。

  • 基类成员函数和派生类成员函数不构成重载
    基类成员和派生类成员的名字一样时会造成遮蔽,这句话对于成员变量很好理解,对于成员函数要引起注意,不管函数的参数如何,只要名字一样就会造成遮蔽。换句话说,基类成员函数和派生类成员函数不会构成重载,如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数,不管它们的参数是否一样。

4、C++派生类构造函数

  • 基类的成员函数可以被继承,可以通过派生类的对象访问;
  • 类的构造函数不能被继承。
  • 在派生类的构造函数中调用基类的构造函数。
Student::Student(char *name, int age, float score): People("小明", 16), m_score(score){ }
  • 派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。
  • 通过派生类创建对象时必须要调用基类的构造函数,这是语法规定。 换句话说,定义派生类构造函数时最好指明基类构造函数;如果不指明,就调用基类的默认构造函数(不带参数的构造函数);如果没有默认构造函数,那么编译失败。

5、派生类的析构函数

  • 和构造函数类似,析构函数也不能被继承。(不用程序员显示调用、编译器负责)
  • 外析构函数的执行顺序和构造函数的执行顺序也刚好相反。
    • 创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。
    • 而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构函数,再执行基类析构函数。

6、C++虚继承和虚基类

  • 多继承(Multiple Inheritance)是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。(容易产生问题,命名冲突。)
  • 虚继承(Virtual Inheritance)
    为了解决多继承时的命名冲突和冗余数据问题,C++ 提出了虚继承,使得在派生类中只保留一份间接基类的成员。在继承方式前面加上 virtual 关键字就是虚继承
//间接基类A
class A{
protected:
    int m_a;
};
//直接基类B
class B: virtual public A{  //虚继承
protected:
    int m_b;
};
  • 虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。其中,这个被共享的基类就称为虚基类(Virtual Base Class)

7、C++虚继承时的构造函数

  • 虚继承中,虚基类是由最终的派生类初始化的,换句话说,最终派生类的构造函数必须要调用虚基类的构造函数。对最终的派生类来说,虚基类是间接基类,而不是直接基类。
  • 这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。
D::D(int a, int b, int c, int d): A(a), B(90, b), C(100, c), m_d(d){ }
void D::display(){
    cout<<"m_a="<<m_a<<", m_b="<<m_b<<", m_c="<<m_c<<", m_d="<<m_d<<endl;
}
  • 例子:
    • 在最终派生类 D 的构造函数中,除了调用 B 和 C 的构造函数,还调用了 A 的构造函数,这说明 D 不但要负责初始化直接基类 B 和 C,还要负责初始化间接基类 A。
    • 而在以往的普通继承中,派生类的构造函数只负责初始化它的直接基类,再由直接基类的构造函数初始化间接基类

你可能感兴趣的:(C++,c++,继承,派生)