首页 > 编程学习 > C++中的继承

C++中的继承

发布时间:2022/11/6 21:52:50

继承

类之间的继承

可以扩展 C + + 中的类,即创建保留基类特征的新类。这个过程称为继承,涉及一个基类和一个派生类: 派生类继承基类的成员,在这些成员之上派生类可以添加自己的成员。

例如,让我们想象一系列的类来描述两种多边形: 矩形(rectangles)和三角形(triangles)。这两个多边形有一些共同的属性,例如计算它们的面积所需的值: 它们都可以简单地用高度和宽度(或基数)来描述。

这可以在类的世界中用一个Polygon类来表示,我们可以从这个类派生出另外两个多边形: 矩形Rectangle)和三角形(Triangle):


Polygon 类将包含多边形所具有的一些通用的成员。如在我们的例子中: 宽度和高度。矩形和三角形将是它的派生类,具有各自特定特征。

从其他类派生的类继承基类的所有可访问成员。这意味着如果一个基类包含一个成员 A,并且我们从它派生一个包含另一个成员 B 的类,那么派生的类将同时包含成员 A 和成员 B。

两个类的继承关系在派生类中声明:

class derived_class_name: public base_class_name { /*...*/ };

  • 其中derived_class_name 是派生类的名称,base _ class _ name 是它所继承的基类的名称。公共访问说明符也可以由其他访问说明符(protected 或 private)。
// 派生类
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b;}
 };

class Rectangle: public Polygon {
  public:
    int area ()
      { return width * height; }
 };

class Triangle: public Polygon {
  public:
    int area ()
      { return width * height / 2; }
  };
  
int main () {
  Rectangle rect;
  Triangle trgl;
  rect.set_values (4,5);
  trgl.set_values (4,5);
  cout << rect.area() << '\n';
  cout << trgl.area() << '\n';
  return 0;
}

  • 矩形和三角形类的对象都包含从Polygon类继承的成员,这些对象是: width、 height 和 set _ value。
  • 类 Polygon 中使用的private访问说明符类似于 private。其唯一的区别实际上与继承有关: 当一个类继承另一个类时,派生类的成员可以访问从基类继承的private成员,但不能访问其私有(private)成员。
  • 通过将 width 和 height 声明为 protected 而不是 private,这些成员也可以从派生类 Recangle 和 Triangle 访问,而不仅仅是从 Polygon 的成员访问。如果它们是公共的,那么可以从任何地方访问它们。


我们可以总结出不同的访问类型,根据这些类型,函数可以通过以下方式访问它们:

访问publicprotectedprivate
类内成员yesyesyes
派生类成员yesyesno
非成员yesnono

  • 其中“非成员”表示来自类外部的任何访问,例如来自 main、来自另一个类或函数的访问。


在上面的示例中,由矩形和三角形继承的成员拥有与其基类 Polygon 相同的访问权限:

Polygon::width           // protected access
Rectangle::width         // protected access

Polygon::set_values()    // public access
Rectangle::set_values()  // public access  
  • 这是因为在每个派生类上使用 public 关键字声明了继承关系:class Rectangle: public Polygon { /* ... */ }

  • 由于 public 是最可访问的级别,因此通过指定此关键字,派生类Recangle将继承与基类中具有相同级别的所有成员。


使用 protected 时,基类的所有公共(public)成员在派生类中继承为 protected。相反,如果指定了最受限制的访问级别(private) ,则所有基类成员都将作为 private 继承。

例如,如果daughter是从mother派生的类,我们定义为:

class Daughter: protected Mother;

  • 如果没有为继承指定访问级别,则编译器为类的假定关键字为 private,而struct 的继承默认为 public。
  • 实际上,C + + 中的大多数继承用例都应该使用public继承。

从基类继承什么?

原则上,公共派生类继承基类的每个成员,除了:

  • 它的构造函数和析构函数
  • 其赋值运算符成员(运算符 =)
  • 它的友元
  • 它的私有成员


即使对基类的构造函数和析构函数的访问不是继承的,它们也会被派生类的构造函数和析构函数自动调用。

除非另有说明,否则派生类的构造函数将调用其基类的默认构造函数(即不带参数的构造函数)。使用初始化列表中用于初始化成员变量的相同语法,可以调用基类的另一个构造函数:

  • 初始化列表:就是在参数列表()与构造函数主体{}之间初始化的一种语法格式,使用冒号:,多个初始化用逗号隔开。


derived_constructor_name (parameters) : base_constructor_name (parameters) {...}

例如:

// 构造函数与派生类 || constructors and derived classes
#include <iostream>
using namespace std;

class Mother {
  public:
    Mother ()
      { cout << "Mother: no parameters\n"; }
    Mother (int a)
      { cout << "Mother: int parameter\n"; }
};

class Daughter : public Mother {
  public:
    Daughter (int a)
      { cout << "Daughter: int parameter\n\n"; }
};

class Son : public Mother {
  public:
    Son (int a) : Mother (a)
      { cout << "Son: int parameter\n\n"; }
};

int main () {
  Daughter kelly(0);
  Son bud(0);
  
  return 0;
}

输出结果:

Mother: no parameters
Daughter: int parameter

Mother: int parameter
Son: int parameter


请注意在创建新的 Daughter 对象时调用 Mother 的构造函数与在创建 Son 对象时调用 Mother 的构造函数之间的区别。区别在于 Daughter 与 Son 的构造函数声明不同:

Daughter (int a)         // 没有特别说明: 调用默认构造函数

Son (int a) : Mother (a) // 调用这个特定的构造函数(有参构造)

多重继承

一个类可以通过简单地指定更多的基类(用逗号分隔)来继承不止一个类。例如,再继承在屏幕上打印 Output 的特定类,我们可以写:

class Rectangle: public Polygon, public Output;

class Triangle: public Polygon, public Output; 


完整的示例:

// 多重继承 || multiple inheritance
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    Polygon (int a, int b) : width(a), height(b) {}
};

class Output {
  public:
    static void print (int i);
};

void Output::print (int i) {
  cout << i << '\n';
}

class Rectangle: public Polygon, public Output {
  public:
    Rectangle (int a, int b) : Polygon(a,b) {}
    int area ()
      { return width*height; }
};

class Triangle: public Polygon, public Output {
  public:
    Triangle (int a, int b) : Polygon(a,b) {}
    int area ()
      { return width*height/2; }
};
  
int main () {
  Rectangle rect (4,5);
  Triangle trgl (4,5);
  rect.print (rect.area());
  Triangle::print (trgl.area());
  return 0;
}

输出结果: 

20
10  

参考网址:https://cplusplus.com/doc/tutorial/inheritance/ 

Copyright © 2010-2022 dgrt.cn 版权所有 |关于我们| 联系方式