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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++primer第15章节详解面向对象程序设计

發(fā)布時(shí)間:2023/12/13 c/c++ 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++primer第15章节详解面向对象程序设计 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言?

  • 面向程序設(shè)計(jì)基于三個(gè)基本概念:數(shù)據(jù)抽象、繼承和動(dòng)態(tài)綁定。繼承和動(dòng)態(tài)綁定可以使得程序定義與其他類相似但是不完全相同的類;使用彼此相似的類編寫程序時(shí)候,可以在一定程度上忽略掉他們的區(qū)別。

OOP概述

  • oop(面向程序的設(shè)計(jì))核心思想是數(shù)據(jù)抽象、繼承和動(dòng)態(tài)綁定。使用數(shù)據(jù)抽象可以將類和接口實(shí)現(xiàn)分離;使用繼承,可以定義相似的類型并對(duì)相似的類型關(guān)系進(jìn)行建模;使用動(dòng)態(tài)綁定,可以一定程度上忽略相似的內(nèi)容,而采用統(tǒng)一的方式使用他們的對(duì)象。

繼承

  • 通過繼承聯(lián)系在一起的類構(gòu)成了一種層次關(guān)系。層次關(guān)系的根部叫做基類,其他類則直接或者間接從基類中繼承來,通過繼承得到的類叫做派生類。基類負(fù)責(zé)定義在層次關(guān)系中所有類共同具備的成員,而每一個(gè)派生類則會(huì)定義各自特有的屬性。

  • 如果派生類想改變基類中包含的特定的函數(shù),根據(jù)自己的實(shí)際情況進(jìn)行定制化的開發(fā),基類需要將這個(gè)函數(shù)聲明為虛函數(shù)。派生類需要使用類派生列表,明確指出他是從哪個(gè)或者哪些基類派生出來的。類派生的形式是:首先一個(gè)分號(hào),后面緊跟著以逗號(hào)分隔的基類列表,其中每個(gè)基類的前面都可以有訪問說明符。
#include<iostream> #include "Sales_item.h" using namespace std;class Quote{ public:string isbn() const;virtual double net_price(size_t n) const; }; class Bulk_quote : public Quote{//Bulk_quote繼承了Quote public:double net_price(size_t n) const override; };int main(){return 0; }
  • 派生類必須在其內(nèi)部對(duì)于所有重新定義的虛函數(shù)進(jìn)行聲明。派生類顯示的注明它將使用哪個(gè)成員函數(shù)改寫基類的虛擬函數(shù),具體的措施是在該函數(shù)的形參列表之后增加一個(gè)override的關(guān)鍵字。

動(dòng)態(tài)綁定

  • 使用動(dòng)態(tài)綁定可以使用相同的代碼分別處理基類和派生類。

double print_total(ostream &os,const Quote &item,size_t n){//計(jì)算并且打印給定數(shù)量的某種書籍所得的費(fèi)用//根據(jù)傳入item的形參的對(duì)象類型調(diào)用Quote::net_price//或者使用Bulk_quote::net_pricedouble ret = item.net_price(n);os << "ISBN: " << item.isbn() << " # sold: " << n << "total due :" << ret << endl;return ret; }
  • 可以使用如下兩種的調(diào)用方式,因?yàn)橄旅娴暮瘮?shù)運(yùn)行版本是由實(shí)參決定的,即在運(yùn)行的時(shí)候選擇函數(shù)的版本,所以動(dòng)態(tài)綁定有時(shí)候又被稱作運(yùn)行時(shí)綁定。在使用基類的引用(或指針)調(diào)用一個(gè)虛函數(shù)的時(shí)候?qū)?huì)發(fā)生動(dòng)態(tài)綁定。
//basic的類型是Quote;bulk的類型是Bulk_quote類型 print_total(cout,basic,20);//調(diào)用Quote的net_price print_total(cout,bulk,20);//調(diào)用Bulk_quote的net_price

定義基類和派生類

  • 完成對(duì)于Quote的定義
  • 繼承關(guān)系中根節(jié)點(diǎn)的類通常會(huì)定義一個(gè)虛析構(gòu)函數(shù),即使該函數(shù)不執(zhí)行任何實(shí)際操作也需要定義析構(gòu)函數(shù)。
class Quote{ public:Quote() = default;Quote(const string &book,double sales_price):bookNo(book),price(sales_price){}string isbn() const{return bookNo};//返回給定數(shù)量的書籍的銷售總額//派生類負(fù)責(zé)改寫并且使用不同的折扣計(jì)算方法virtual double net_price(size_t n) const{return n * price;}virtual ~Quote() = default;//對(duì)于析構(gòu)函數(shù)進(jìn)行動(dòng)態(tài)綁定 private:string bookNo;//書籍的ISBN序列號(hào) protected:double price = 0.0;//代表普通狀態(tài)下不打折的價(jià)格 };

成員函數(shù)和繼承

  • 基類需要將兩種成員函數(shù)區(qū)別開來:1,基類希望派生類進(jìn)行覆蓋的函數(shù);2,基類需要派生類直接繼承但是不要改變的函數(shù)。對(duì)于前者,基類通常將其定義為虛函數(shù),在使用指針或者引用調(diào)用虛擬函數(shù)的時(shí)候,該調(diào)用將會(huì)動(dòng)態(tài)綁定。根據(jù)引用或者指針?biāo)壎ǖ膶?duì)象不同,該引用可能會(huì)執(zhí)行基類或者執(zhí)行某個(gè)派生類。
  • 任何構(gòu)造函數(shù)之外的非靜態(tài)函數(shù)都可以是虛函數(shù)。關(guān)鍵字virtual只可以出現(xiàn)在類內(nèi)部的聲明之前而不能用于對(duì)于類外部的函數(shù)的定義。對(duì)于基類聲明的虛函數(shù),則該函數(shù)在派生類中隱式地也是虛函數(shù)。成員函數(shù)沒有被聲明為虛函數(shù),那么解析過程發(fā)生在編譯的時(shí)候而不是運(yùn)行的時(shí)候;即虛函數(shù)解析過程發(fā)生在運(yùn)行的時(shí)候,動(dòng)態(tài)綁定,動(dòng)態(tài)執(zhí)行。

訪問控制與繼承

  • 派生類可以繼承定義在基類中的成員,但是派生類成員不一定具有對(duì)于從基類繼承而來的成員的訪問權(quán)。派生類可以訪問公有成員但是不能訪問私有成員。protected用于派生類可以訪問,但是禁止其他用戶進(jìn)行訪問。

定義派生類

  • 派生類必須通過派生列表明確指出它是從哪個(gè)(哪些)基類派生而來的。類派生的形式是:首先一個(gè)分號(hào),后面緊跟著以逗號(hào)分隔的基類列表,其中每個(gè)基類的前面都可以有訪問說明符之一,比如public、protected和private。
  • 派生類必須將其繼承而來的成員函數(shù)中需要覆蓋的那些函數(shù)重新聲明
  • 大多數(shù)類都繼承自一個(gè)類,這種機(jī)制叫做單繼承

派生類中的虛函數(shù)

  • 派生類經(jīng)常(但不是總是)覆蓋定義它繼承的虛函數(shù),如果派生類中沒有覆蓋基類中的繆一個(gè)虛函數(shù),派生類會(huì)直接繼承自基類中的對(duì)于虛函數(shù)的定義。
  • 在形參列表后面、或者在const成員函數(shù)的const關(guān)鍵字后面、或者在引用成員函數(shù)的引用限定符后面添加一個(gè)關(guān)鍵字override。

派生類對(duì)象以及派生類向基類的類型轉(zhuǎn)換

  • 派生類所具有的對(duì)象,不僅包含繼承自基類的對(duì)象還具有自己新創(chuàng)建的對(duì)象。但是在一個(gè)對(duì)象中,繼承自基類的部分和派生類自定義的部分不一定是連續(xù)存儲(chǔ)的,就是在物理存儲(chǔ)邏輯上,二者不一定占據(jù)連續(xù)一段存儲(chǔ)空間。
Quote item; //基類對(duì)象Bulk_quote bulk; //派生類對(duì)象Quote *p = &item; //p指向item(Quote)對(duì)象p = &bulk; //p指向bulk(Bulk_quote)對(duì)象的Quote部分Quote *r = &bulk; // r綁定到bulk(Bulk_quote)對(duì)象的Quote部分
  • 上面這段代碼通常稱之為派生類到基類的類型轉(zhuǎn)換,這個(gè)過程是由編譯器隱式執(zhí)行的。即可以將把派生類對(duì)象或者派生類對(duì)象的引用在需要基類引用的地方。同樣可以將派生類對(duì)象的指針用在需要基類指針的地方。

派生類構(gòu)造函數(shù)

  • 盡管派生類對(duì)象中含有從基類繼承而來的成員,但是派生類不可以直接初始化這些成員,派生類需要使用基類的構(gòu)造函數(shù)來初始化他的基類部分。派生類對(duì)象的基類部分與派生類對(duì)象的自己的數(shù)據(jù)成員都是在構(gòu)造函數(shù)的初始化階段執(zhí)行初始化操作的。

  • 派生類將自己繼承自基類的那部分交由基類進(jìn)行初始化,然后初始化派生類自己定義的成員,最后運(yùn)行派生類的構(gòu)造函數(shù)。除非我們特定指出,否則派生類對(duì)象的基類部分會(huì)像數(shù)據(jù)成員一樣被默認(rèn)初始化。但是如果想使用其他的基類構(gòu)造函數(shù),需要以類名加圓括號(hào)的實(shí)參列表的形式為構(gòu)造函數(shù)提供初始化數(shù)值。這些實(shí)參會(huì)幫助編譯器決定使用哪個(gè)構(gòu)造函數(shù)來初始化派生類對(duì)象的基類部分。

派生類使用基類的成員

  • 派生類可以訪問基類的公有成員和受保護(hù)的成員。即派生類的作用域嵌套在基類的作用域之內(nèi)。即對(duì)于派生類的成員來說,使用派生類的成員和使用基類成員的方式是沒有不同的。

繼承與靜態(tài)成員

  • 基類定義了一個(gè)靜態(tài)成員,則在整個(gè)繼承體系中只存在該成員的唯一定義。從基類中派生出多少個(gè)派生類,對(duì)于每個(gè)靜態(tài)成員來說都只存在唯一的實(shí)例。

派生類的聲明

  • 派生類的聲明需要包含類名但是不包含他的派生列表。

被用作基類的類

  • 如果要將某一個(gè)類用作基類,則該類必須已經(jīng)定義而不是簡簡單單的聲明。
  • 一個(gè)類不可以派生它本身。即一個(gè)類是基類,同時(shí)他也可以是一個(gè)派生類。比如D1是Base的派生類,而D2又是D2的派生類。那么Base是D1的直接基類,同時(shí)也是D2的間接基類。
  • 對(duì)于最終的一個(gè)派生類來說,他會(huì)包含直接基類的所有成員和每一個(gè)間接基類的所有對(duì)象。

防止繼承的發(fā)生

  • 防止自定義的類被繼承,那么就在類的名字后面跟上一個(gè)關(guān)鍵字final。
  • class NoDerived final{} //NoDerived不能作為基類

類型轉(zhuǎn)換與繼承

  • 常規(guī)情形下,將引用/指針綁定到一個(gè)對(duì)象上,則引用或者指針的類型應(yīng)該與對(duì)象的類型是一致的。或者對(duì)象的類型含有一個(gè)可以接受的const類型轉(zhuǎn)換規(guī)則。存在繼承關(guān)系的類是一個(gè)特殊的存在。
  • 基類的指針或者引用綁定到派生類的對(duì)象上,有一層很重要的含義就是不確定被綁定的對(duì)象的真實(shí)類型是基類還是派生類。

靜態(tài)類型與動(dòng)態(tài)類型

  • 表達(dá)式的靜態(tài)類型是編譯的時(shí)候已知的,是變量聲明時(shí)的類型或則表達(dá)式生成的類型;動(dòng)態(tài)類型是變量或者表達(dá)式表示內(nèi)存中的對(duì)象類型,動(dòng)態(tài)類型直到運(yùn)行時(shí)才可知。
  • 如果表達(dá)式既不是指針也不是引用,那么他的動(dòng)態(tài)類型和靜態(tài)類型是一致的。

不存在從基類向派生類的隱式類型轉(zhuǎn)換

  • 因?yàn)橐粋€(gè)基類對(duì)象是派生類中的一部分,所以不存在基類向派生類的類型轉(zhuǎn)換,因?yàn)榛惒豢梢栽L問派生類中不存在的成員。
  • 既是一個(gè)基類指針或者引用綁定在一個(gè)派生類度向上,也不可以執(zhí)行從基類到派生類的轉(zhuǎn)換。
  • 如果基類中存在多個(gè)虛擬函數(shù),在進(jìn)行類型轉(zhuǎn)換的時(shí)候,可以使用dynamic_cast請(qǐng)求一個(gè)類型轉(zhuǎn)換,該轉(zhuǎn)換的安全檢查將會(huì)在運(yùn)行的時(shí)候進(jìn)行檢查。如果我們已經(jīng)知道將某個(gè)基類裝換為派生類是安全的,可以使用static_cast來強(qiáng)制覆蓋掉編譯器的檢查工作。

在對(duì)象之間不存在類型轉(zhuǎn)換

  • 使用派生類對(duì)象為一個(gè)基類對(duì)象進(jìn)行初始化或者賦值的時(shí)候,只有派生類對(duì)象中的基類部分會(huì)被拷貝、移動(dòng)和賦值;他的派生類部分將會(huì)被忽略掉。

?

?

?

?

?

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的C++primer第15章节详解面向对象程序设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。