最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++繼承機制、概念、語法、作用域與轉換規(guī)則詳解

 更新時間:2026年05月25日 09:25:52   作者:Zhang~Ling  
本文介紹了C++中繼承的概念與定義,重點講解了繼承的訪問權限變化、基類與派生類間的轉換規(guī)則以及作用域中的隱藏機制,感興趣的朋友一起看看吧

1. 繼承的概念以及定義

1.1 繼承的概念

繼承(inheritance)機制是面向對象程序設計使代碼可以復用的重要手段,它允許我們在保持原有類特性的基礎上進行擴展,增加方法(成員函數(shù))和屬性(成員變量),這樣產(chǎn)生新的類,稱派生類。繼承呈現(xiàn)了面對象程序設計的層次結構,體現(xiàn)了由簡單到復雜的認知過程。以前我們接觸的函數(shù)層次的復用,繼承設計是類設計層次的復用。

//將公有成員都放到Person類中
class Person {
public:
	//進入校園/圖書館/實驗室刷二維碼等身份認證
	void identify() {
		//......
	}
protected:
	string _name = "張三";//姓名
	string _address;      //地址
	string _tel;          //電話
	int _age = 18;        //年齡
};
class Student :public Person//Student類繼承自Person
{
public:
	//學習
	void study() {
	}
protected:
	int _stuid;//學號
};
class Teacher :public Person//Student類繼承自Person
{
public:
	//授課
	void teacher() {
	}
protected:
	string title;//職稱
};
int main() {
	Student s;
	Teacher t;
	s.identify();
	t.identify();
}

在上述代碼中,TeacherStudent都具有Person類的特征,那么我們就可以讓TeacherStudent都繼承自Person,再在各自類中寫入各自的特性。這樣對Person中的成員進行一個復用,又保證了不同類的特點,避免了重復定義。

1.2 繼承的定義

1.2.1 定義格式

舉個例子:下面的Person是基類,也稱作父類。Student是派生類,也稱作子類。(基類/派生類,父類/子類)。

繼承方式對照??:

1.2.2繼承基類成員訪問方式的變化

  1. 基類private成員在派生類中無論以什么樣的方式繼承都是不可見的。這里的不可見是指基類的私有成員還是被繼承到了派生類對象中,但是語法上限制派生類對象不管類里面還是類外面都不能去訪問它。
  2. 基類private成員在派生類中是不能被訪問,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為protected。(這里可以看出保護成員限定符是因為繼承才出現(xiàn)的)。
類成員/繼承方式public繼承protected繼承private繼承
基類的public成員派生類的public成員派生類的protected成員派生類的private成員
基類的protected成員派生類的protected成員派生類的protected成員派生類的private成員
基類的private成員在派生類中不可見在派生類中不可見在派生類中不可見
  1. 我們總結一下上面的表格,基類的私有成員在派生類中都是不可見的?;惖钠渌蓡T在派生類中的訪問方式就等于:Min(成員在基類的訪問限定符,繼承方式),其中:public>protected>private。
  2. 使用關鍵字class時默認的繼承方式是private,使用struct時默認的繼承方式時public,最好顯示的寫出繼承方式。
  3. 在實際運用中一般使用的都是public繼承,幾乎很少使用protected/private繼承,也不提倡使用protected/private繼承,因為protected/private繼承下來的成員都只能在派生類的類里面使用,實際中擴展維護性不強。
    簡單演示一下:
//示例演示三種繼承關系下基類成員的各類型成員訪問關系的變化
class Person {
public:
	void Print() {
		cout << _name << endl;
	}
protected:
	string _name = "張三";//姓名
private:
	int _age;
};
//class Student:protected Person
//class Student:private Person
class Student :private Person
{
protected:
	int _stunum;//學號
};

1.3 繼承類模板

基類是類模板的時候,需要指定一下類域,否則編譯會報錯,找不到"push_back"標識符。原因是因為stack<int>實例化時,也實例化了vector<int>了。但是模板是按需實例化,push_back等成員函數(shù)未實例化,所以找不到push_back這個成員。

namespace ZL
{
	//例如stack繼承自vector
	template<class T>
	class stack:public std::vector<T>
	{
	public:
		void push(const T& x) {
			vector<T>::push_back(x);
			//push_back(x);這樣寫是不對的
		}
		void pop() {
			vector<T>::pop_back();
		}
		const T& top() {
			return vector<T>::back();
		}
		bool empty() {
			return vector<T>::empty();
		}
	};
}
int main() {
	ZL::stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	while (!st.empty()) {
		cout << st.top() << " ";
		st.pop();
	}
	return 0;
}

2. 基類和派生類間的轉換

  1. 通常情況下我們把一個類型的對象賦值給另一個類型的指針或者引用時,存在類型轉換,中間會產(chǎn)生臨時對象,所以需要加const,如:int a =1; const double& d = a;public繼承中,就是一個特殊處理的例外,派生類對象可以賦值給基類的指針/基類的引用,而不需要加const,這里的指針或者引用,可能指向基類對象,也可能指向派生類對象。
  2. 派生類對象賦值給基類對象是通過基類的拷貝構造函數(shù)或者賦值重載函數(shù)完成的,這個過程就像派生類自己定義部分成員切掉一樣,所以也被叫做切割或者切片。

  • 指針與引用轉換(圖1、圖2):
    • Person*Person& 指向/引用 Student 對象時,僅僅是視角的改變。
    • 特點: 底層的內(nèi)存結構沒有變化,Student 對象依然完整存在(包括 _No),只是通過基類指針或引用只能“看”到和訪問基類部分(_name, _sex, _age),無法訪問派生類特有的成員。這就像給 Student 戴上了一個 Person 的面具。
  • 值拷貝轉換(圖3):
    • Student 對象賦值給 Person 對象時,發(fā)生了切片。
    • 特點: 這是一個物理上的拷貝過程。系統(tǒng)只復制了 Student 中屬于 Person 的那部分數(shù)據(jù)(_name, _sex, _age)到一個全新的、獨立的 Person 對象中。Student 特有的部分(_No)被直接丟棄(切掉),且兩個對象在內(nèi)存中是完全獨立的個體。
  1. 基類對象不能賦值給派生類對象,派生類對象可以通過拷貝構造賦值給基類對象。
//將公有成員都放到Person類中
class Person {
public:
	//進入校園/圖書館/實驗室刷二維碼等身份認證
	void identify() {
		//......
	}
protected:
	string _name = "張三";//姓名
	string _address;      //地址
	string _tel;          //電話
	int _age = 18;        //年齡
};
class Student :public Person//Student類繼承自Person
{
public:
	//學習
	void study() {
	}
protected:
	int _stuid;//學號
};
int main() {
	Student sobj;
	//派生類對象可以直接賦值給基類的指針/引用
	Person* pp = &sobj;
	Person& rp = sobj;
	//派生類對象可以直接賦值給基類對象是通過調(diào)用拷貝構造完成的
	Person pobj = sobj;
	//基類對象不能直接賦值給派生類對象,否則編譯會報錯
	//sobj = pobj;
	return 0;
}
  1. 基類的指針或者引用可以通過強制類型轉換賦值給派生類的指針或者引用。但必須是基類的指針是指向派生類對象時才是安全的。這里的基類如果是多態(tài)類型,可以使用RTTI(Run-Time Type Information)的dynamic_cast來進行識別后進行安全轉換。

3.繼承中的作用域

3.1 隱藏規(guī)則

  1. 在繼承體系中,基類和派生類都有獨立的作用域。
  2. 派生類和基類中有同名成員,派生類成員將屏蔽基類對同名成員的直接訪問,這種情況叫隱藏。(在派生類成員函數(shù)中,可以使用 基類::基類成員顯示訪問)
class Person {
public:
	//進入校園/圖書館/實驗室刷二維碼等身份認證
	void identify() {
		//......
	}
protected:
	string _name = "張三";//姓名
	string _num="222222222222";      //身份證號
};
class Student :public Person
{
public:
	//學習
	void Print() {
		cout << "姓名:" << _name << endl;
		//這里出現(xiàn)了同名的成員,默認都會調(diào)用派生類的成員
		// 如果不加類限定符號則基類的_num就會被隱藏
		cout << "身份證號碼:" <<Person:: _num << endl;
		cout << "學號:" << _num << endl;
	}
protected:
	string _num = "11111";  //學號
};
int main() {
	Student s1;
	s1.Print();
	return 0;
}

上述代碼的Student_numPerson的_num構成隱藏關系,這樣的代碼很危險能運行但不正確。
3. 需要注意的是如果是成員函數(shù)的隱藏,只需要函數(shù)名相同就構成隱藏。
4. 注意在實際中繼承體系里面最好不要定義同名的成員。

3.2 考察繼承作用域相關的選擇題

3.2.1 A和B中兩個func構成什么關系?

A.重載 B.隱藏 C.重寫 D.無關
只需要函數(shù)名相同就構成隱藏,哪怕參數(shù)不同。選擇B。

3.2.2 下面程序的編譯運行結果是什么?

A. 編譯報錯 B.運行報錯 C.正常運行
b.fun()調(diào)用的是派生類的fun()沒有參數(shù)編譯就不通過,基類的fun()被隱藏了,選擇A。
正確調(diào)用基類fun():

b.A::fun();

題目:

class A {
public:
	void fun() {
		cout << "func()" << endl;
	}
};
class B :public A
{
public:
	void fun(int i) {
		cout << "func(int i)" << endl;
	}
};
int main() {
	B b;
	b.fun(10);
	b.fun();
	return 0;
}

到此這篇關于C++繼承機制詳解上:概念、語法、作用域與轉換規(guī)則的文章就介紹到這了,更多相關C++繼承的概念內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++中mutable與volatile的深入理解

    C++中mutable與volatile的深入理解

    這篇文章主要給的阿加介紹了關于C++中mutable與volatile的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • C語言與C++中const的用法對比

    C語言與C++中const的用法對比

    C語言中的const與C++有很大的不同,在C語言中用const修飾的變量仍是一個變量,表示這個變量是只讀的,不可顯示地更改,而在C++中用const修飾過后,就變成常量了
    2022-04-04
  • C++代碼實現(xiàn)貪吃蛇小游戲

    C++代碼實現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細介紹了C++貪吃蛇小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C語言中分支和循環(huán)的6種實現(xiàn)形式總結

    C語言中分支和循環(huán)的6種實現(xiàn)形式總結

    C語言時一門結構化的程序設計語言,這篇文章主要介紹了C語言中的分支和循環(huán)的6種實現(xiàn)形式,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-04-04
  • static_cast,dynamic_cast,reinterpret_cast,const_cast的區(qū)別及用法詳解

    static_cast,dynamic_cast,reinterpret_cast,const_cast的區(qū)別及用法詳解

    以下是對static_cast,dynamic_cast,reinterpret_cast,const_cast的區(qū)別及用法進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-09-09
  • C語言實現(xiàn) 數(shù)據(jù)類型占多少字節(jié)指針占多少字節(jié)

    C語言實現(xiàn) 數(shù)據(jù)類型占多少字節(jié)指針占多少字節(jié)

    這篇文章主要介紹了 C語言 數(shù)據(jù)類型占多少字節(jié)指針占多少字節(jié)的實例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • C++私有繼承(一)

    C++私有繼承(一)

    這篇文章主要介紹了C++私有繼承,在私有繼承當中,基類的公有成員和保護成員都會成為派生類的私有成員。這意味著基類的方法都會被private關鍵字描述,我們可以在派生類中使用它,但類對象無法直接調(diào)用,下面來看看詳細內(nèi)容吧
    2022-01-01
  • c++實現(xiàn)值機系統(tǒng)

    c++實現(xiàn)值機系統(tǒng)

    這篇文章主要為大家詳細介紹了c++實現(xiàn)在線值機系統(tǒng)程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 解析ActiveMQ的使用說明總結

    解析ActiveMQ的使用說明總結

    本篇文章是對ActiveMQ的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++實現(xiàn)LeetCode(111.二叉樹的最小深度)

    C++實現(xiàn)LeetCode(111.二叉樹的最小深度)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(111.二叉樹的最小深度),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評論

天门市| 临澧县| 云南省| 成武县| 简阳市| 苏尼特左旗| 四会市| 镇巴县| 弋阳县| 丽水市| 博野县| 阜南县| 林芝县| 嘉祥县| 拜城县| 迁西县| 偃师市| 嘉峪关市| 图木舒克市| 桂东县| 郯城县| 尼玛县| 徐州市| 杭锦后旗| 连云港市| 洛扎县| 左权县| 东兴市| 南汇区| 开原市| 南澳县| 和硕县| 南昌市| 仪陇县| 淮南市| 马尔康县| 湘阴县| 固原市| 梧州市| 温宿县| 辽阳县|