c++ 继承与派生(二)

旧城等待, 2023-05-29 03:12 93阅读 0赞

先让我们回顾一下上次的要点:

  1. 继承与派生的概念
  2. 派生类的构造函数和析构函数的执行顺序与规则
  3. 多继承的声明与实现
  4. 基类成员访问原则
  5. 赋值兼容性
  6. 虚基类的概念

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

在继承机制中,基类的构造函数和析构函数是不能继承的,也就是说,基类的构造函数不能作为派生类的构造函数,派生类的构造函数负责对来自基类数据成员和新增加的数据成员进行初始化。
构造函数的调用顺序如下:
(1)基类的构造函数
(2)对象成员的构造函数有多个时按声明的顺序
(3)派生类的构造函数
派生类的构造实例:

  1. class B {
  2. public:
  3. B() {
  4. cout << "ConstructingB..." << endl;
  5. }
  6. };
  7. class C {
  8. public:
  9. C(){
  10. cout << "ConstructingC..." << endl;
  11. }
  12. };
  13. class D :public B
  14. {
  15. private:
  16. C c1;
  17. public:
  18. D() {
  19. cout << "ConstructingD..." << endl;
  20. }
  21. };
  22. int main()
  23. {
  24. D d1;
  25. return 0;
  26. }

运行结果为
Constructing B…
Constructing C…
Constructing D…

析构函数与构造函数执行顺序相反

派生类构造函数和析构函数的构造规则:
(1)如基类中定义了默认的构造函数,且该默认构造函数能够完成派生类对象中基本成员的构造,则派生类构造函数无需显示调用基类构造函数,直接调用基类的默认构造函数即可。
例:

  1. class Base {
  2. public:
  3. Base() {
  4. a = 0; }
  5. Base(int i) {
  6. a = i; }
  7. protected:
  8. int a;
  9. };
  10. class Derived :public Base {
  11. //隐式地调用基类地构造函数
  12. public:
  13. Derived() {
  14. b = 0; }
  15. Derived(int i) {
  16. b = i; }
  17. void Print()
  18. {
  19. cout << "a =" << a << ",b=" << b << endl;
  20. }
  21. private:
  22. int b;
  23. };
  24. int main()
  25. {
  26. Derived d1;
  27. Derived d2(12);
  28. d1.Print();
  29. d2.Print();
  30. return 0;
  31. }

运行结果:
a =0,b=0
a =0,b=12
(2)若基类中定义了有参数地构造函数,或者所定义的默认构造函数不能完成基类成员的构造,则需要用到“成员初始化列表”。
因此派生类构造函数定义的一般格式如下:
派生类名(参数类表):基类参数构造(参数列表1),子对象成员(参数列表)…
{
派生类构造函数体
}

示例:

  1. class Date {
  2. private:
  3. int year, month, day;
  4. public:
  5. Date(int y = 2000, int m = 6, int d = 10)
  6. {
  7. year = y;
  8. month = m;
  9. day = d;
  10. }
  11. void Print()
  12. {
  13. cout << year << "-" << month << "-" << day << endl;
  14. }
  15. };
  16. class Student {
  17. protected:
  18. int number;
  19. string name;
  20. char gender;
  21. public:
  22. Student()
  23. {
  24. number = 0;
  25. name = "NO NAME";
  26. gender = 'M';
  27. }
  28. Student(int n, string s, char x)
  29. {
  30. number = n;
  31. name = s;
  32. gender = x;
  33. }
  34. };
  35. class Undergraduate :public Student {
  36. public:
  37. Undergraduate(int n, string s, char x, int a, int y, int m, int d) :
  38. Student(n, s, x), birth(y, m, d)
  39. {
  40. age = a;
  41. }
  42. Undergraduate()
  43. {
  44. age = 0;
  45. }
  46. void Print()
  47. {
  48. cout << "number:" << number << endl;
  49. cout << "name:" << name << endl;
  50. cout << "gender:" << gender << endl;
  51. cout << "age:" << age << endl;
  52. cout << "birthday:";
  53. birth.Print();
  54. }
  55. private:
  56. int age;
  57. Date birth;
  58. };
  59. int main()
  60. {
  61. Undergraduate st1;
  62. Undergraduate st2(1001, "Zhao", 'F', 20, 2009, 6, 11);
  63. st1.Print();
  64. st2.Print();
  65. return 0;
  66. }

运行结果:
number:0
name:NO NAME
gender:M
age:0
birthday:2000-6-10
number:1001
name:Zhao
gender:F
age:20
birthday:2009-6-11

多继承

多继承下派生类的声明格式如下:
class 派生类名:继承方式1基类名1,继承方式2基类名2,…
{
派生类类体;
}

派生类构造函数执行顺序时先执行所有基类的构造函数,再执行派生类本身的构造函数,处于同一层次的各基类构造函数取决于声明派生类时所指定各基类顺序,与派生类构造函数中所定义的成员初始化列表的各项顺序无关。相对应的是,析构函数的调用顺序与构造函数完全相反。

基类成员访问和赋值兼容性

若多个基类中定义有同名成员,则派生类对这些同名成员的访问可能存在冲突。为避免可能出现的成员访问冲突,需要用成员名限定的方法显式地指定要访问的成员。

  1. #include<iostream>
  2. using namespace std;
  3. class MP3player {
  4. public:
  5. void Play()
  6. {
  7. cout << "Play mp3 music" << endl;
  8. }
  9. };
  10. class Videoplayer {
  11. public:
  12. void Play()
  13. {
  14. cout << "Play vider" << endl;
  15. }
  16. };
  17. class MP4player :public MP3player, public Videoplayer {
  18. public:
  19. /**/
  20. };
  21. int main()
  22. {
  23. MP4player Mp4;
  24. Mp4.MP3player::Play();
  25. Mp4.Videoplayer::Play();
  26. return 0;
  27. }

为解决上述成员访问冲突问题,在main()函数中,采用了成员名限定的方法对具体基类的同名成员进行访问,格式如下:
基类名::成员函数
即在成员名Play()前显示指定该成员所属基类,这样有效的避免了对该成员访问的二义性错误,同样对于基类的数据成员,该原则同样适用。

当派生类中定义了与基类中同名的成员时,则从基类中继承得到的成员被派生类的同名成员覆盖,派生类对基类成员的直接访问将被派生类中该成员取代,为访问基类成员,必须采用成员名限定方法

发表评论

表情:
评论列表 (有 0 条评论,93人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++ 继承派生

    一、继承和派生的基本概念 “继承”就是支持代码重用的机制之一 二、什么是派生? 书本概念;从一个或多个以前定义的类(基类)产生新类的过程称为派生。这个新类称为派生

    相关 c++ 类的继承派生

    c++类的继承与派生   一、基本概念 1、类的继承,是新的类从已有类那里得到已有的特性。或从已有类产生新类的过程就是类的派生。原有的类称为基类或父类,产生的新类称为

    相关 c++ 继承派生(一)

    要点: 1. 继承与派生的概念 2. 派生类的构造函数和析构函数的执行顺序与规则 3. 多继承的声明与实现 4. 基类成员访问原则 5. 赋值兼容性 6. 虚基类

    相关 继承派生

    定义:类的继承,是新的类从已有类那里得到已有的特性,从已有类产生新类的过程就是类的派生,原有的类称为基类,产生的新类称为派生类;一个派生类,可以同时有多个基类,这种情况称为多继

    相关 C++ 类的继承派生

    继承性是面向对象程序设计最重要的特性之一,使软件有了可重用性,C++提供的类的继承机制。 继承与派生的概念 一个新类从已有的类那里获得已有的特性,这种现象称为类的继承。

    相关 C++ 继承派生

    一、继承方式 公有继承 基类中公有成员和保护成员访问权限不变,私有成员变为不可访问。 私有继承(默认) 基类中公有成员和保护成员变为私有成员,私有成员变为不可

    相关 继承派生

    继承 - 继承指的是类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题 - 继承是一种创建新类的方式,在python中,新建的类可以继...