C++ 继承

C++ 继承

面向对象编程中最重要的概念之一就是继承。继承允许我们用另一个类来定义一个类,这样可以更容易地创建和维护一个应用程序。这也提供了重用代码功能和快速实现的机会。

在创建一个类时,程序员可以指定新类应该继承现有类的成员,而不是完全编写新的数据成员和成员函数。这个现有类被称为基类,新类被称为派生类。

继承的概念实现了”is a”的关系。例如,哺乳动物是动物,狗是哺乳动物,因此狗也是动物,依此类推。

基类和派生类

一个类可以从多个类派生,这意味着它可以从多个基类继承数据和函数。为了定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表列出了一个或多个基类,具有如下形式:

class derived-class: access-specifier base-class

其中access-specifier是以下之一: public,protected,private ,base-class是先前定义的类的名称。如果未使用access-specifier,则默认为private。

考虑一个基类 Shape 及其派生类 Rectangle 如下:

#include <iostream>

using namespace std;

// Base class
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }

   protected:
      int width;
      int height;
};

// Derived class
class Rectangle: public Shape {
   public:
      int getArea() { 
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;

   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   return 0;
}

当上述代码被编译和执行时,会产生以下结果−

Total area: 35

访问控制和继承

派生类可以访问其基类的所有非私有成员。因此,基类成员如果不想被派生类的成员函数访问,应该在基类中声明为私有成员。

根据谁可以访问它们,我们可以总结出不同的访问类型如下:

Access public protected private
Same class yes yes yes
Derived classes yes yes no
Outside classes yes no no

派生类继承所有基类的方法,但有以下几个例外:

  • 基类的构造函数、析构函数和拷贝构造函数。
  • 基类的重载运算符。
  • 基类的友元函数。

继承类型

当从一个基类派生出一个类时,可以通过 公有(public)、保护(protected) 或者 私有(private) 继承来继承基类。继承类型由访问说明符(access-specifier)指定。

我们几乎不使用 保护(protected) 或者 私有(private) 继承,但常用的是 公有(public) 继承。在使用不同类型的继承时,应遵循以下规则−

  • 公有(public)继承 − 当从一个 公有(public) 基类派生出一个类时,基类的 公有(public) 成员成为派生类的 公有(public) 成员,基类的 保护(protected) 成员成为派生类的 保护(protected) 成员。基类的 私有(private) 成员对于派生类而言是不可直接访问的,但可以通过对基类的 公有(public)保护(protected) 成员的调用来访问。

  • 保护(protected)继承 − 当从一个 保护(protected) 基类派生出一个类时,基类的 公有(public)保护(protected) 成员成为派生类的 保护(protected) 成员。

  • 私有(private)继承 − 当从一个 私有(private) 基类派生出一个类时,基类的 公有(public)保护(protected) 成员成为派生类的 私有(private) 成员。

多重继承

一个C++类可以从多个类继承成员,下面是其扩展语法−

class derived-class: access baseA, access baseB....

其中access可以是公共、受保护、或者私有之一,并且将针对每个基类进行设置,它们将以逗号分隔,如上所示。让我们尝试以下示例:

#include <iostream>

using namespace std;

// Base class Shape
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }

   protected:
      int width;
      int height;
};

// Base class PaintCost
class PaintCost {
   public:
      int getCost(int area) {
         return area * 70;
      }
};

// Derived class
class Rectangle: public Shape, public PaintCost {
   public:
      int getArea() {
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;
   int area;

   Rect.setWidth(5);
   Rect.setHeight(7);

   area = Rect.getArea();

   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   // Print the total cost of painting
   cout << "Total paint cost: $" << Rect.getCost(area) << endl;

   return 0;
}

当上述代码被编译和执行时,它产生如下结果 –

Total area: 35
Total paint cost: $2450

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程