【C++之保护继承】输入和输出 num, name, sex, age, addr

题目要求

将例5.3的程序片段补充和改写成一个完整、正确的程序,用保护继承方式。在程序中应包括输入数据的函数。

——谭浩强的《C++面向对象程序设计》第5章习题第3小题

例5.3的程序片段:

#include <iostream>
#include <string>
using namespace std;
class Student // 声明基类
{
public: // 基类无公用成员

protected: // 基类保护成员
	int num;
	string name;
	char sex;
};

class Student1 : protected Student // 以 protected 方式声明派生类 Student1
{
public: // 派生类公用成员
	void get_value1(); // 输入派生类数据 
	void display1(); // 输出两个数据成员的值
	
private: // 派生类私有成员
	int age;
	string addr;
};

void get_value1() // 输入派生类数据 
{
	cin >> num >> name >> sex; // 输入保护基类数据成员
	cin >> age >> addr;        // 输入派生类数据成员
}
void Student1::display1() // 输出两个数据成员的值
{
	cout << "num: " << num << endl;      // 引用基类的保护成员
	cout << "name: " << name << endl;    // 引用基类的保护成员
	cout << "sex: " << sex << endl;      // 引用基类的保护成员
	cout << "age: " << age << endl;      // 引用派生类的私有成员
	cout << "address: " << addr << endl; // 引用派生类的私有成员
}

int  main()
{
	Student1 stud1;     // 定义派生类 Student1 的对象 stud1
	stud1.get_value1(); // 调用派生类的公用成员函数,输入派生类两个数据成员的值
	stud1.display1();   // 调用派生类的公用成员函数,输出派生类中两个数据成员的值
	system("pause");
	return 0;
}

保护继承

在基类的访问属性继承方式在派生类中的访问属性
private(私有)protected(保护)不可访问
public(公用)protected(保护)protected(保护)
protected(保护)protected(保护)protected(保护)
  1. 当派生类的继承方式为 protected 继承属性时,在派生类中,基类的公有成员和保护成员均作为派生类的保护成员派生类的成员可以直接访问它们,而派生类的成员无法访问基类的私有成员

如例5-3中:

void Student1::display1() // 输出两个数据成员的值
{
	cout << "num: " << num << endl;      // 引用基类的保护成员
	cout << "name: " << name << endl;    // 引用基类的保护成员
	cout << "sex: " << sex << endl;      // 引用基类的保护成员
	...
}

num、name、sex 均为基类的保护成员,派生类 Student1 的成员函数 display1 可以访问直接它们。

如果把 num、name、sex 改为私有成员,即:

protected: // 基类保护成员
	int num;
	string name;
	char sex;

改为

private: // 基类保护成员
	int num;
	string name;
	char sex;
};

则程序报错如下:

“Student::num”: 无法访问 private 成员(在“Student”类中声明)
“Student::name”: 无法访问 private 成员(在“Student”类中声明)
“Student::sex”: 无法访问 private 成员(在“Student”类中声明)

因为当派生类的继承方式为 protected 时,派生类的成员不能访问基类的私有成员。

  1. 在派生类的外部,派生类的对象无法访问基类的全部成员。
    例如在 main 函数内修改 num 的值:
int  main()
{
	Student1 stud1;     // 定义派生类 Student1 的对象 stud1
	stud1.num = 5;		// 错误。类外访问基类的保护成员
	stud1.get_value1(); // 调用派生类的公用成员函数,输入派生类两个数据成员的值
	stud1.display1();   // 调用派生类的公用成员函数,输出派生类中两个数据成员的值
	system("pause");
	return 0;
}

会出现报错:

“Student::num”: 无法访问 protected 成员(在“Student”类中声明)

因为 num 是基类 student 的保护成员,由于派生类是保护继承,在派生类中仍受保护,但外界不能用 stud1.num 形式访问它。
保护继承对比公用继承,保护继承在类外不能访问基类所有成员,而公用继承在类外可以访问基类的公用成员。

  1. 如果基类只进行了一次派生,则保护继承和私有继承的功能完全相同,但保护继承可以进一步派生,而私有继承则不可以,两者具有实质性差别。

三种继承方式比较

在基类的访问属性继承方式在派生类的访问属性
privatepublic不可访问
privateprivate不可访问
privateprotected不可访问
publicpublicpublic
publicprivateprivate
publicprotectedprotected
protectedpublicprotected
protectedprivateprivate
protectedprotectedprotected

补充改写后的程序

/*
*************************************************************************
@file:    main.cpp
@date:   2020.11.29
@author: Xiaoxiao
@brief:   保护继承方式输入和输出 num,name,sex,age,addr
@blog:    https://blog.csdn.net/weixin_43470383/article/details/110204364
*************************************************************************
*/
#include <iostream>
#include <string>
using namespace std;
class Student // 声明基类
{
public: // 基类无公用成员

protected: // 基类保护成员
	int num;
	string name;
	char sex;
};

class Student1 : protected Student // 以 protected 方式声明派生类 Student1
{
public: // 派生类公用成员
	void get_value1(); // 输入派生类数据 
	void display1(); // 输出两个数据成员的值
	
private: // 派生类私有成员
	int age;
	string addr;
};

// 其实要改的只有这里,get_value1() 前面加上 Student1::
// 原因是在类外声明成员函数,需要在函数名前面加类名限定,具体参考我之前的博客:
// https://editor.csdn.net/md/?articleId=109298731
void Student1::get_value1() // 输入派生类数据 
{
	cin >> num >> name >> sex; // 输入保护基类数据成员
	cin >> age >> addr;        // 输入派生类数据成员
}
void Student1::display1() // 输出两个数据成员的值
{
	cout << "num: " << num << endl;      // 引用基类的保护成员
	cout << "name: " << name << endl;    // 引用基类的保护成员
	cout << "sex: " << sex << endl;      // 引用基类的保护成员
	cout << "age: " << age << endl;      // 引用派生类的私有成员
	cout << "address: " << addr << endl; // 引用派生类的私有成员
}

int  main()
{
	Student1 stud1;     // 定义派生类 Student1 的对象 stud1
	stud1.get_value1(); // 调用派生类的公用成员函数,输入派生类两个数据成员的值
	stud1.display1();   // 调用派生类的公用成员函数,输出派生类中两个数据成员的值
	system("pause");
	return 0;
}

运行结果

运行结果
输入:
8 Xiaoxiao m 20 Guangzhou

输出:
num: 8
name: Xiaoxiao
sex: m
age: 20
address: Guangzhou

结果和上两篇博客相同。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不雨_亦潇潇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值