题目要求
将例5.1的程序片段补充和改写成一个完整、正确的程序,用公用继承方式。在程序中应包括输入数据的函数,在程序运行时输入 num, name, sex, age, addr 的值,程序应输出以上5个数据。
——谭浩强的《C++面向对象程序设计》第5章习题第1小题
例5.1的程序片段:
class Student // 声明基类
{
public: // 基类公用成员
void get_value() // 输入基类数据的成员函数
{
cin >> num >> name >> sex;
}
void display() // 输出基类数据的成员函数
{
cout << "num: " << num << endl;
cout << "name: " << name << endl;
cout << "sex: " << sex << endl;
}
private: // 基类私有成员
int num;
string name;
char sex;
};
class Student1 : public Student // 以 public 方式声明派生类 Student1
{
public:
void get_value_1() // 输入派生类数据
{
cin >> age >> addr;
}
void display_1() // 输出两个数据成员的值
{
// cout << "num: " << num << endl; // 企图引用基类的私有成员,错误
// cout << "name: " << name << endl; // 企图引用基类的私有成员,错误
// cout << "sex: " << sex << endl; // 企图引用基类的私有成员,错误
cout << "age: " << age << endl; // 引用派生类的私有成员
cout << "address: " << addr << endl; // 引用派生类的私有成员
}
private:
int age;
string addr;
};
int main()
{
Student1 stud; // 定义派生类 Student1 的对象 stud
stud.get_value(); // 调用基类的公用成员函数,输入基类两个数据成员的值
stud.get_value_1(); // 调用派生类的公用成员函数,输入派生类两个数据成员的值
stud.display(); // 调用基类的公用成员函数,输出基类中两个数据成员的值
stud.display_1(); // 调用派生类的公用成员函数,输出派生类中两个数据成员的值
return 0;
}
继承与派生
-
C++的继承机制旨在实现程序或软件的重用。
所谓继承是在现有类 A 的基础上构建一个新类 B 。
类 A称为基类或父类,类 B 称作派生类或子类。
子类从父类获得其已有的特性,这种现象称作类的继承;
从另一个角度看从父类产生子类,又称作类的派生。 -
通过单个基类派生子类的声明格式为:
class 派生类名 : [继承方式] 基类名
{ 派生类新增成员声明 } ;
继承方式:public、private、protected。系统缺省为 private。
例如:现有基类为student,通过单继承构建一个派生类student1,继承方式为 public:
class Student1 : public Student // 以 public 方式声明派生类 Student1
- 派生类中的成员包括从基类继承的成员和本类新增的成员。
继承基类成员体现了同一基类的子类都具有的共性,而新增加的成员体现了子类的个性。
在声明派生类时增加成员,它体现了派生类对基类功能的扩充。
公用继承
在基类的访问属性 | 继承方式 | 在派生类中的访问属性 |
---|---|---|
private(私有) | public(公用) | 不可访问 |
public(公用) | public(公用) | public(公用) |
protected(保护) | public(公用) | protected(保护) |
- 当派生类的继承方式为 public(公有)属性时,在派生类中,基类的公有成员和保护成员在派生类中的访问属性没有变化;即分别作为派生类的公有成员和保护成员,派生类中新增的成员(函数)可以直接访问它们。
例如:
void get_value_1() // 输入派生类数据
{
get_value(); // 调用基类的公用成员函数,输入3个数据成员的值
cin >> age >> addr;
}
在派生类 Student1 中的函数 get_value_1 中引用基类 Student 中的函数 get_value,是允许的。
-
**在派生类外,可以访问公用基类中的公用成员。**基类的私有成员在派生类内外都不可访问。基类的派生成员在派生类中也是受保护的,在派生类内可以访问,但在派生类外不可访问。
-
基类的私有成员在派生类中没有称为派生类的私有成员,它仍然是基类的私有成员,只有基类的成员函数可以引用它。派生类的成员不能直接访问基类的私有成员。保护私有成员是一条重要的原则。
如例5-1程序中:
void display_1()
{
// cout << "num: " << num << endl; // 企图引用基类的私有成员,错误
// cout << "name: " << name << endl; // 企图引用基类的私有成员,错误
// cout << "sex: " << sex << endl; // 企图引用基类的私有成员,错误
cout << "age: " << age << endl; // 引用派生类的私有成员
cout << "address: " << addr << endl; // 引用派生类的私有成员
}
在派生类 Student1 中的函数 display_1 中引用基类 Student 的私有数据成员 num, name, sex,是不允许的。
- 如果想要引用公用基类的私有成员,有两种方法:
(1)通过基类的公有成员函数访问基类的私有数据成员。
如例5-1程序中:
stud.get_value(); // 调用基类的公用成员函数,输入基类两个数据成员的值
stud.get_value_1(); // 调用派生类的公用成员函数,输入派生类两个数据成员的值
stud.display(); // 调用基类的公用成员函数,输出基类中两个数据成员的值
stud.display_1(); // 调用派生类的公用成员函数,输出派生类中两个数据成员的值
(2)在派生类的成员函数中调用基类的公有成员函数,访问基类的私有数据成员。
例如:
void display_1()
{
display(); // 调用基类的公用成员函数,输出两个数据成员的值
cout << "age: " << age << endl; // 引用派生类的私有成员
cout << "address: " << addr << endl; // 引用派生类的私有成员
}
补充改写后的程序
/*
*************************************************************************
@file: main.cpp
@date: 2020.11.25
@author: Xiaoxiao
@brief: 公用继承方式输入和输出 num,name,sex,age,addr
@blog: https://blog.csdn.net/weixin_43470383/article/details/110138820
*************************************************************************
*/
#include <iostream>
using namespace std;
class Student // 声明基类
{
public: // 基类公用成员
void get_value() // 输入基类数据的成员函数
{
cin >> num >> name >> sex;
}
void display() // 输出基类数据的成员函数
{
cout << "num: " << num << endl;
cout << "name: " << name << endl;
cout << "sex: " << sex << endl;
}
private: // 基类私有成员
int num;
char name[10];
char sex;
};
class Student1 : public Student // 以 public 方式声明派生类 Student1
{
public:
void get_value_1() // 输入派生类数据
{
get_value(); // 调用基类的公用成员函数,输入3个数据成员的值
cin >> age >> addr;
}
void display_1()
{
display(); // 调用基类的公用成员函数,输出两个数据成员的值
cout << "age: " << age << endl; // 引用派生类的私有成员
cout << "address: " << addr << endl; // 引用派生类的私有成员
}
private:
int age;
char addr[30];
};
int main()
{
Student1 stud1; // 定义派生类 Student1 的对象 stud1
stud1.get_value_1(); // 调用派生类的公用成员函数,输入派生类两个数据成员的值
stud1.display_1(); // 调用派生类的公用成员函数,输出派生类中两个数据成员的值
system("pause");
return 0;
}
运行结果
输入:
8 Xiaoxiao m 20 Guangzhou
输出:
num: 8
name: Xiaoxiao
sex: m
age: 20
address: Guangzhou