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

简介: 【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(保护)

当派生类的继承方式为 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 时,派生类的成员不能访问基类的私有成员。


在派生类的外部,派生类的对象无法访问基类的全部成员。

例如在 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 形式访问它。

对比公用继承,保护继承在类外不能访问基类所有成员,而公用继承在类外可以访问基类的公用成员。


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

三种继承方式比较



在基类的访问属性

继承方式

在派生类的访问属性

private

public

不可访问

private

private

不可访问

private

protected

不可访问

public

public

public

public

private

private

public

protected

protected

protected

public

protected

protected

private

private

protected

protected

protected


补充改写后的程序


/*
*************************************************************************
@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 
#include 
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


结果和上两篇博客相同。

相关文章
|
16天前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
48 16
|
12天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
37 5
|
2月前
|
编译器 C++ 开发者
【C++】继承
C++中的继承是面向对象编程的核心特性之一,允许派生类继承基类的属性和方法,实现代码复用和类的层次结构。继承有三种类型:公有、私有和受保护继承,每种类型决定了派生类如何访问基类成员。此外,继承还涉及构造函数、析构函数、拷贝构造函数和赋值运算符的调用规则,以及解决多继承带来的二义性和数据冗余问题的虚拟继承。在设计类时,应谨慎选择继承和组合,以降低耦合度并提高代码的可维护性。
40 1
【C++】继承
|
6月前
|
编译器 C++
【C++】详解C++的继承
【C++】详解C++的继承
|
3月前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
104 11
|
3月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
70 1
|
3月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
57 1
|
3月前
|
安全 编译器 程序员
C++的忠实粉丝-继承的热情(1)
C++的忠实粉丝-继承的热情(1)
27 0
|
3月前
|
编译器 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
50 0
|
3月前
|
程序员 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
57 0