題目要求
将例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;
}
會出現報錯:
因為 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 <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
結果和上兩篇部落格相同。