派生类从基类继承时有三个步骤,第一个步骤是吸收基类成员,吸收了基类中除构造函数和析构函数之外的所有数据成员和函数成员,第二个步骤就是修改基类成员,包括修改对基类成员的访问属性和覆盖基类成员,第三个步骤是添加新成员。第二个步骤中修改对基类成员的访问属性可以通过派生类的继承方式控制。
类的成员有public(公有)、protected(保护)和private(私有)三种访问属性。类的继承方式也有public(公有继承)、protected(保护继承)和private(私有继承)三种。派生类通过不同的继承方式可以获得对基类成员的不同的访问属性。派生类对基类成员的访问主要有两种,一种是派生类的新增成员对继承的基类成员的访问,另一种是派生类的对象对继承的基类成员的访问。下面会详细讲。
通过对象访问类的成员属于外部访问,只能访问类的公有成员。
派生类的继承方式为public,即公有继承时,对基类中的公有成员和保护成员的访问属性都不变,而对基类的私有成员则不能访问。具体说,就是基类的公有成员和保护成员被继承到派生类中以后同样成为派生类的公有成员和保护成员,派生类中新增成员对他们可以直接访问,派生类的对象只能访问继承的基类公有成员。但是派生类的新增成员和派生类的对象都不能访问基类的私有成员。
写一个公有继承的简单例子:
- #include <iostream>
- using namespace std;
- class Base // 基类Base的声明
- {
- public: // 公有成员函数
- void SetTwo(int a, int b) { x=a; y=b; }
- int GetX() { return x; }
- int GetY() { return y; }
- private: // 私有数据成员
- int x;
- int y;
- };
- class Child : public Base // 派生类的声明,继承方式为公有继承
- {
- public: // 新增公有成员函数
- void SetThree(int a, int b, int c) { SetTwo(a, b); z=c; }
- int GetZ() { return z; }
- private: // 新增私有数据成员
- int z;
- };
- int main()
- {
- Child child; // 声明Child类的对象
- child.SetThree(1, 2, 3); // 设置派生类的数据
- cout << "The data of child:"<<endl;
- cout << child.GetX() << "," << child.GetY() << "," << child.GetZ() << endl;
- return 0;
- }
程序运行结果是:
The data of child:
1,2,3
上面的程序声明了一个基类Base,又声明了Base类的派生类Child,最后是主函数部分。派生类Child从基类Base中继承了除构造函数和析构函数外的所有数据成员和函数成员,这些再加上派生类Child的新增成员就组成了Child类的全部。类Child的继承方式为公有继承,基类Base的所有公有成员在派生类Child中的访问属性不变,都可以直接访问,所以Child类的SetThree函数可以直接调用Base类的SetTwo函数。基类公有成员SetTwo、GetX和GetY都变成了Child类外部接口的一部分。但是上面说过,派生类不能访问基类的私有成员,所以Child类不能访问Base类的x和y。
主函数中首先定义了派生类Child的对象child,然后通过对象child调用了派生类Child的新增公有函数SetThree和GetZ,还调用了从基类Base继承的公有成员函数GetX和GetY。
通过这个例子,派生类对基类成员的两种访问方式:派生类的新增成员对继承的基类成员的访问和通过派生类的对象对继承的基类成员的访问,都讲到了。