C++继承机制深度解析
立即解锁
发布时间: 2025-08-19 01:36:32 阅读量: 26 订阅数: 29 AIGC 


C++面向对象编程入门与实践
### C++ 继承机制深度解析
#### 1. 员工数据管理与抽象基类
在处理员工数据时,我们会遇到不同类型的员工,如经理、科学家和普通劳工。以下是输入员工数据的示例:
```plaintext
Enter golf club dues: 1000000
Enter data on manager 2
Enter last name: Bradley
Enter number: 124
Enter title: Vice - President
Enter golf club dues: 500000
Enter data for scientist 1
Enter last name: Hauptman - Frenglish
Enter number: 234234
Enter number of pubs: 999
Enter data for laborer 1
Enter last name: Jones
Enter number: 6546544
```
程序会将这些数据回放显示:
```plaintext
Data on manager 1
Name: Wainsworth
Number: 10
Title: President
Golf club dues: 1000000
Data on manager 2
Name: Bradley
Number: 124
Title: Vice - President
Golf club dues: 500000
Data on scientist 1
Name: Hauptman - Frenglish
Number: 234234
Number of publications: 999
Data on laborer 1
Name: Jones
Number: 6546544
```
更复杂的程序会使用数组或其他容器来管理大量员工对象。
这里引入了“抽象”基类的概念。以员工类(`employee`)为例,我们并不直接定义该基类的对象,它仅作为其他类派生的基础。劳工类(`laborer`)与员工类操作相同,虽看似多余,但将其作为独立类强调了所有类都源自员工类。而且,若未来要修改劳工类,无需更改员工类的声明。仅用于派生其他类的类,有时被宽泛地称为抽象类,即不会创建该类的实际实例(对象)。
在基类和派生类中都没有构造函数,编译器遇到类似 `manager m1, m2;` 的定义时,会自动使用默认构造函数创建对象,先调用经理类的默认构造函数,再调用员工类的默认构造函数。员工类中的 `getdata()` 和 `putdata()` 函数用于接收用户输入的姓名和编号,并显示这些信息。经理类和科学家类中的同名函数会使用员工类的函数,同时完成自身的特定任务。例如,经理类的 `getdata()` 函数会询问用户职位和高尔夫俱乐部会费,`putdata()` 函数则显示这些值;科学家类的这些函数用于处理发表文章的数量。
#### 2. 继承与图形形状
在之前的 `CIRCLES` 程序中,我们看到了用类表示屏幕上可显示的图形圆。实际上,除了圆,还有正方形、三角形等其他形状。“形状种类”暗示了“形状”与具体形状(如圆和正方形)之间的继承关系。利用这种关系,我们可以编写更健壮、更易理解的程序。
下面创建一个形状类(`shape`)作为基类,派生出圆类(`circle`)、矩形类(`rect`)和三角形类(`tria`)。以下是 `MULTSHAP` 程序的代码:
```cpp
// multshap.cpp
// balls, rects, and polygons
#include "msoftcon.h" //for graphics functions
////////////////////////////////////////////////////////////////
class shape //base class
{
protected:
int xCo, yCo; //coordinates of shape
color fillcolor; //color
fstyle fillstyle; //fill pattern
public: //no - arg constructor
shape() : xCo(0), yCo(0), fillcolor(cWHITE),
fillstyle(SOLID_FILL)
{ } //4 - arg constructor
shape(int x, int y, color fc, fstyle fs) :
xCo(x), yCo(y), fillcolor(fc), fillstyle(fs)
{ }
void draw() const //set color and fill style
{
set_color(fillcolor);
set_fill_style(fillstyle);
}
};
////////////////////////////////////////////////////////////////
class circle : public shape
{
private:
int radius; //(xCo, yCo) is center
public:
circle() : shape() //no - arg constr
{ }
//5 - arg constructor
circle(int x, int y, int r, color fc, fstyle fs)
: shape(x, y, fc, fs), radius(r)
{ }
void draw() const //draw the circle
{
shape::draw();
draw_circle(xCo, yCo, radius);
}
};
////////////////////////////////////////////////////////////////
class rect : public shape
{
private:
int width, height; //(xCo, yCo) is upper - left corner
public:
rect() : shape(), height(0), width(0) //no - arg ctor
{ } //6 - arg ctor
rect(int x, int y, int h, int w, color fc, fstyle fs) :
shape(x, y, fc, fs), height(h), width(w)
{ }
void draw() const //draw the rectangle
{
shape::draw();
draw_rectangle(xCo, yCo, xCo + width, yCo + height);
set_color(cWHITE); //draw diagonal
draw_line(xCo, yCo, xCo + width, yCo + height);
}
};
////////////////////////////////////////////////////////////////
class tria : public shape
{
private:
int height; //(xCo, yCo) is tip of pyramid
public:
tria() : shape(), height(0) //no - arg constructor
{ } //5 - arg constructor
tria(int x, int y, int h, color fc, fstyle fs) :
shape(x, y, fc, fs), height(h)
{ }
void draw() const //draw the triangle
{
shape::draw();
draw_pyramid(xCo, yCo, height);
}
};
////////////////////////////////////////////////////////////////
int main()
{
init_graphics(); //initialize graphics system
circle cir(40, 12, 5, cBLUE, X_FILL); //create circle
rect rec(12, 7, 10, 15, cRED, SOLID_FILL); //create rectangle
tria tri(60, 7, 11, cGREEN, MEDIUM_FILL); //create triangle
cir.draw(); //draw all shapes
rec.draw();
tri.draw();
set_cursor_pos(1, 25); //lower - left corner
return 0;
}
```
该程序运行后会生成三种不同的形状:蓝色的圆、红色的矩形和绿色的三角形。形状类包含所有形状共有的特征,如位置、颜色和填充模式。各个具体形状类有更特定的属性,如圆有半径,矩形有高度和宽度。形状类的 `draw()` 函数处理所有形状的通用任务:设置颜色和填充模式。圆、矩形和三角形类中的重载 `draw()` 函数在确定颜色和模式后,负责绘制各自的形状。形状类是抽象类的一个例子,因为实例化该类的对象没有实际意义,只有具体形状才能显示自身。
#### 3. 公共继承与私有继承
C++ 提供了多种方式来微调对类成员的访问。派生类的声明方式就是一种访问控制机制。之前的例子使用的是公共派生类,如 `class manager : public employee`。这里的 `public` 关键字表示派生类的对象可以访问基类的公共成员函数,而替代方案是 `private` 关键字。使用 `private` 关键字时,派生类的对象无法访问基类的公共成员函数。由于对象永远无法访问类的私有或受保护成员,所以基类的任何成员都不能被派生类的对象访问。
以下是一个展示不同访问组合的示例程序 `PUBPRIV`:
```cpp
// pubpriv.cpp
// tests publicly - and privately - derived classes
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class A //base class
{
private:
int privdataA; //(functions have the same access
protected: //rules as the data shown here)
int protdataA;
public:
int pubdataA;
};
////////////////////////////////////////////////////////////////
class B : public A //publicly - derived class
{
public:
void funct()
{
int a;
a = privdataA; //error: no
```
0
0
复制全文
相关推荐










