天天看點

【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;
}
           

會出現報錯:

因為 num 是基類 student 的保護成員,由于派生類是保護繼承,在派生類中仍受保護,但外界不能用 stud1.num 形式通路它。

【C++之保護繼承】輸入和輸出 num, name, sex, age, addr題目要求保護繼承三種繼承方式比較補充改寫後的程式運作結果

對比公用繼承,保護繼承在類外不能通路基類所有成員,而公用繼承在類外可以通路基類的公用成員。

  1. 如果基類隻進行了一次派生,則保護繼承和私有繼承的功能完全相同,但保護繼承可以進一步派生,而私有繼承則不可以,兩者具有實質性差别。

三種繼承方式比較

在基類的通路屬性 繼承方式 在派生類的通路屬性
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 <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;
}
           

運作結果

【C++之保護繼承】輸入和輸出 num, name, sex, age, addr題目要求保護繼承三種繼承方式比較補充改寫後的程式運作結果

輸入:

8 Xiaoxiao m 20 Guangzhou

輸出:

num: 8

name: Xiaoxiao

sex: m

age: 20

address: Guangzhou

結果和上兩篇部落格相同。

繼續閱讀