日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++语言基本概念(5)

發布時間:2023/12/9 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++语言基本概念(5) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

面向對象編程與面向過程的一個根本區別,就是面向對象編程在虛擬的計算機世界構造出了形形×××的對象,很顯然這些對象之間必然要發生關系,如何區別描述這些關系也是面向對象這門課所要研究的問題。我們都知道其中有非常多的概念,有些概念還非常抽象,根本難以理解,特別是如果邏輯思維不好的話,會根本被這些概念繞進去。那么這里我們怎么去理解這些東西呢?以我的經驗,我想我們還是從生活來理解,我們相像一下計算機描述的世界同現實世界是一模一樣的。我們講兩個人,比喻說你和你爸是父子關系,那你的朋友張三與張三的爸是不是也是父子關系呢,當你描述你的某樣特征繼承你爸時候,實際上這種繼承關系也發生在張三與張三的爸之上。那么你可能會說,我們兩者之間繼承的肯定不一樣啊,是的,繼承的結果是不一樣的,但繼承的邏輯是一樣的。由此我們推出在現實世界中描述繼承雖然理解上好像是兩個對象之間的事情,但實際上它的邏輯映射是類結構上。所以討論計算機中C++語言中的繼承也一樣,它也是通過描述兩個不同的類之間關系,來映射出兩個對象之間繼承結果。因此,兩個類之間具有繼承邏輯定義,就說明由這兩個類創建的對象具有繼承的結果,這個結果就是作為子類生成子對象可以訪問作為父類的父對象一些特定函數和屬性。這樣理解,也可能會讓你產生一種誤會,比喻,說你跟你爸,你能訪問你爸什么呢?顯然這里的訪問不能作交互理解,更多的理解是你具有了父親的一些特征。所以說子類創建的對象自然具有了父類的函數與屬性。定義一個派生類的格式:

class 派生類名:繼承方式(public/protect/private):父類名

{

? 派生成員函數;

? 派生成員數據;

}

從上面的格式來看,繼承方式同前面的控制屬性使用相同的關鍵字。那么它們兩者之間有什么關聯呢?我們前面說控制屬性是站在兩個對象能否相互訪問的立場來看,比喻說一個屬性或者一個函數,是public,那么另外的對象它是可以直接訪問到這個對象的。那么前面所說的繼承方式是不是也一樣呢?顯然不一樣,因為前面的控制屬性是兩個對象之間,而現在繼承方式是兩個類之間,明顯類是一種抽象概念,是不具有訪問控制這一說法。類只是通過函數表現某種繼承特征。這一點,我們可以這樣相像,比喻說爸爸有雙眼皮,那么兒子可能有雙眼皮,也可能沒有。從雙眼皮這個特征上說,它在子類中表現為可以具備也可能不具備。因此,繼承方式實際上表明了父類中的某個函數在子類中因為繼承方式的不同,子類可能不具備父類的某個函數特征。所以C++設計了三個不同的繼承方式,通過這三個不同方式,子類有選擇的繼承了父類的不同特征。具體概念要求就是子類降一級。具體如下:

【1】public(公有繼承):繼承時保持基類中各成員屬性不變,外部類對象可以通過繼承類對象訪問基類的公有和保護成員,但不能訪問基類中private成員。派生類的其它成員函數也可以訪問基類中public和protect成員,但不能訪問private成員。

【2】protect(保護繼承):繼承時基類中的public和protect成員在派生類中變成protect,外部類對象不能通過派生類對象訪問基類所有成員,但派生類其它成員函數可以訪問基類中的public和protect成員,同樣也不能訪問private成員

【3】private(私有繼承):繼承時基類中的public和protect成員在派生類中變成private,外部類對象不能通過派生類對象訪問基類所有成員,但派生類其它成員函數可以訪問基類中的public和protect成員,同樣也不能訪問private成員。那可能有人會問私有繼承與保護繼承有什么區別,這里區別在于C++是有多種繼承,實際上進行了私有繼承,就不可以再往下繼承了。

前面我們講述了派生類與子類之間關于繼承方式不同而影響到不同的控制屬性。那么接下來我們思考三個問題?而這三個問題顯然非常明顯,都具有共同性,就是同名屬性與現名函數問題。我們分成三個點來學習:

【1】構造函數 父類與子類都具有構造函數,并且構造函數還一樣,入參不一樣。那么很顯然,子類對象初始化時如何構造子類,而子類構造函數怎么構造父類構造函數。這就說出另一個問題,就是基類的構造函數能否被繼承呢?按照前面的理解,似乎構造構造函數只要不是private都可以繼承,但實際上構造函數是不能繼承的,為什么構造函數不能被繼承,這一點需要從構造函數的出發點來說明,構造函數它不是普通的成員函數,它是在創建對象時調用的,也就是說它是編譯器特定的一種函數,它是由編譯器來控制的函數,只有當類實例化成對象時,構造函數才會被調用。所以如果子類能繼承基類構造函數,當基類創建對象時就會同時創建出一個父類對象出來,這是不可能的 。對象只有一個。那么學過C++的人都知道,實際上子類構造函數是可以調用父類構造函數進行初始化的,那這種調用其出發點是干什么呢?因為子類的構造函數在構造子類對象時,因為子類繼承了父類的一些特定成員,這些成員需要通過父類的構造函數才能初始化。所以子類需要通過父類的構造函數構造出父類的成員來。

【2】同名成員屬性或者多繼承時來自共同祖先但不同中間祖先,如下圖所示中x屬性,在A對象和B對象都有,顯然,C對象中x是繼承自哪個父類呢?從下圖中顯然說不清楚?

上圖是繼承的兩個父類具有相同成員屬性。那么三重繼承中最上層的屬性肯定被中間層繼承,最底層的類如果使用祖先類成員又會分不清楚哪個父親了。

我們必須避免這種情況,避免這種情況有一種方法可以使用A::x來調用指定來自哪個繼承父類。對后面一種情況,多重繼承我們還有另外一種說法,就是雖然有兩個父親,但我只想一個祖先成員。這時候可以使用虛繼承。

【3】同名函數 顯然父類與子類是一定會出現同名函數,并且這些同名函數還具有相同的形參。那么如果子類繼承了父類的同名函數,對子類對象來說,使用這個同名函數究竟是父類的函數還是子類的呢?這里面有什么規律呢?

同名函數在覆蓋的前提下,對由不同層次的類生成的對象調用的都是自身的函數,而不是繼承來的函數。但是我們還有一種類型自動轉型概念,這個是C++這種動態語言的一個特點,比喻說 A p*; B b; p=&b;這時候雖然指針p的類型還是A,但是已經指向b 對象了,那么這種情況下同名函數是哪一個呢?令人驚訝的是這時候它還是A的output函數,這時候它就不具有多態性。這一點,如果想不通的話,可能需要借助匯編或者編譯器去了解底層實現細節。

要想實現在指針或者引用的條件,同名函數使用真實對象自身的同名函數,需要將其基類的函數聲明為虛函數 virtual。虛函數是指當某個函數在不同層次的類中完全相同時,在程序執行時根據不同對象,應該調用哪個層次的函數時,我們采用了一種虛函數的機制。如果這個函數不加vitual,則通過指針或者引用來調用這個函數時,這個函數只具備一態性。而如果這個函數加了virtual,則通過指針或者引用來調用這個函數時,這個函數具備多態性。從虛函數可以實現多態性的情況,如果基類內部函數全部是虛函數,并且這些虛函數都沒有實現,也就是純虛函數時,這個類一般稱之為抽像類。抽象類通常是不能產生對象的,但是可以聲明指針,并通過指針指向抽象類的子類,實現多態性。

轉載于:https://blog.51cto.com/acreep/711371

總結

以上是生活随笔為你收集整理的C++语言基本概念(5)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。