Effective C++學習第九天

條款32:確定你的public繼承塑模出is-a模型

? ? ? ?class D(derived)以public形式繼承class B(base),則每一個類型為D的對象同時也是一個類型為B的對象,反之不成立,因此B比D表現出更加一般化的概念,而D比B表現出更特殊化的概念。在C++領域里面,任何函數如果希望獲得一個類型為B的實參,都也愿意接受一個類型為D的對象,這就是is-a(是一種)的關系;代碼分享:

class ractangle{

public:

virtual void setheight(int newheight);

virtual void setwidth(int newwidth);

virtual int height( ) const;

virtual int width( ) const;

};

void makebigger(rectangle &r){

int oldheight=r.height( );

r.setwidth(r.width( )+10);

assert(r.height()==oldheight);//assert為真

}

class square:public rectangle{ ...};

square s;

assert(s.width()==s.height( ));//assert為真

makebiggle(s);

assert(s.width()==s.height( ));//asseert為真 ,為什么s沒有發生變化;

在本例分析中,某些可施行在矩形身上的事情(寬度可獨立于高度被修改)卻沒辦法施行在正方形身上(寬度和高度一樣),但public主張,能夠施行在base class對象上的每一件事情,都能施行于derived class對象上,所以正方形和矩形的例子中不滿足is-a模型;pulic就意味著is-a模型,因此在繼承中確定你的class之間的關系,并合理塑造它們

條款33:避免遮掩繼承而來的名稱(繼承而導致的作用域問題)

? ? ? ? ? 在public繼承中,derived class中的成員函數會將base class中重名的成員函數覆蓋掉,從而出現因繼承導致成員函數調用問題;因此使用public繼承但又不繼承那些重載函數,這就違背了public繼承中的is-a原則;

? ? ? ? ?如果你想繼承base class并加上重載函數,而你希望重新定義或者復寫其中一部分,那么你必須為那些原本會被遮掩的每個名稱引用一個using的聲明,否則某些你希望繼承的名稱會被遮掩;

? ? ? ? ?如果derived以private方式繼承的base,如果使用using聲明,那么給定名稱的函數會在derived中都可見,這并不是我們希望達到的目的,這時候我們可以使用一個簡單的轉交函數;

class base{

public:

virtual void mf1()=0;

virtual void mf1(int);

...

};

class derived:private base {

public:

? virtual void mf1( ){//轉交函數

? ? ? ? base::mf1( );//inline函數

?}

};

條款34:區分接口繼承和實現繼承

? ? ? ? ? public繼承分為函數接口繼承和函數實現繼承;

? ? ? ? ? 1)對于pure virtual函數,它有兩個特性,它們必須被任何“繼承了它們”的具象class重新聲明,而且它們在抽象class中通常沒有定義,因此聲明一個pure virtual函數的目的是為了derived class只繼承接口(只具體接口繼承)

? ? ? ? ?引申:我們可以給pure virtual函數提供定義,也就是說你可以給base中的pure virtual函數提供一份實現代碼,C++并不會發出警告和錯誤,但調用它的唯一途徑就是:調用時明確指出其class路徑;(一直以為pure virtual函數不能在base內實現)

? ? ? ? ?2)derived class繼承函數接口,但是impure virtual函數會提供一份實現代碼,derived class可能會賦寫它;聲明簡樸的impure virtual 函數的目的,是讓derived classes繼承該函數的接口和缺省實現(具體指定接口繼承和缺省實現繼承);

? ? ? ? ?如果在繼承過程中,derived class中沒有重新定義virtual class,那么就默認使用base class中的virtual函數;如果兩個class都共享著一份相同的性質,可以把這份相同的性質搬到base class中,從而避免代碼重復,這是典型的面向對象的設計方法;

? ? ? ?3)對于一個non-virtual函數,意味著它并不打算在derived class中有不同的行為,實際上一個non-virtual成員函數所表現出來的不變性凌駕其特異性,因此不管derived class變得多特異化,它的行為都不可以被改變;聲明一個non-virtual函數的目的是為了令derived class繼承函數的接口及一份強制性的實現(具體指定接口及強制性實現繼承);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382384.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382384.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382384.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Effective C++學習第十天

條款36:絕不重新定義繼承而來的non-virtual函數non-virtual函數執行的是靜態綁定,在編譯器就已經決定,因此對象對用的函數只和指針的類型有關,而與指針所指的對象無關;記住non-virtual函數的性質:不變性凌駕…

Redis運維和開發學習筆記(7) 內存管理和過期策略

Redis運維和開發學習筆記(7) 內存管理和過期策略 文章目錄Redis運維和開發學習筆記(7) 內存管理和過期策略內存回收策略惰性刪除定時任務刪除maxmemory過期策略allkeys-lru主從搭建測試搭建完畢主從測試結果volatile-lru測試結果volatile-ttl測試結果allkeys-lru內存回收策略 …

Effective C++學習第十一天

條款41:了解隱式接口和編譯期多態面向對象編程世界總是以顯式接口(源碼可見的接口)和運行期多態(virtual)解決問題;對于templates及泛型編程的世界,隱式接口和編譯期多態顯得更加重要&#xff1…

Redis源碼分析(零)學習路徑筆記

文章目錄第一階段第二階段 熟悉Redis的內存編碼結構第三階段 熟悉Redis數據類型的實現第四階段 熟悉Redis數據庫的實現第五階段 熟悉客戶端和服務器端的代碼實現第六階段 這一階段主要是熟悉Redis多機部分的代碼實現關于測試方面的文件有一些工具類的文件如下SORT命令的實現一些…

Effective C++學習第十二天

條款47:請使用traits classes表現類型信息STL有五類迭代器分類,input迭代器(只讀,一次,向前)、output迭代器(可寫,一次,向前)、forward迭代器(讀/…

Redis源碼分析(一)redis.c //redis-server.c

Redis源碼分析(一)redis.c //redis-server.c 入口函數 int main() 4450 int main(int argc, char **argv) {4451 initServerConfig();4452 if (argc 2) {4453 ResetServerSaveParams();4454 loadServerConfig(argv[1]);4455 …

Linux 學習

1.linux文本命令行語言環境設置命令 查看當前語言環境: echo ¥LANG 修改: LANG選擇的語言環境’ 引申:https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬鏈接和軟連接 linux中文件的儲存方式&#xf…

vivo C/C++工程師視頻面試總結 20180802

1.自我介紹:有點兒緊張了,直接把自己簡歷上的一些信息信息說了一遍,說完之后在介紹了一下自己的平時的愛好和興趣,感覺面試官沒有理我,直接進入下一環節了。 2.項目詳情:主要是自己最近的一個項目和自己負…

Redis源碼分析(二)redis-cli.c

文章目錄1. int main()2. parseOptions(int argc, char **argv) 進行ip和port的改變3. lookupCommand(char *name) 查找命令,判斷命令合法3.2 strcasecmp(name,cmdTable[j].name)3.1 redisCommand cmdTable[]4. cliSendCommand(int argc, char **argv)4.1 cliConnec…

C語言中有bool變量嗎?

1.C/C中定義的數據類型: C語言中定義了6種基本數據類型:short,int,long,float,double,char 4種構造類型:數組,結構體(struct),共用類型(union),枚舉類型(enum) 指針類型和空類型 C語…

redis源碼剖析(三)——基礎數據結構

文章目錄SDS鏈表字典這篇文章關于 Redis 的基礎數據:SDS SDS (Simple Dynamic String)是 Redis 最基礎的數據結構。直譯過來就是”簡單的動態字符串“。Redis 自己實現了一個動態的字符串,而不是直接使用了 C 語言中的字符串。 sds 的數據結…

C++迭代器使用錯誤總結

指針和迭代器的區別: 迭代器: (1)迭代器不是指針,是類模板,表現的像指針。他只是模擬了指針的一些功能,通過重載了指針的一些操作符,->,*, --等封裝了指針,是一…

redis源碼剖析(四)跳表

文章目錄整數集合跳躍表壓縮列表總結整數集合 當一個集合只包含整數,且這個集合的元素不多的時候,Redis 就會使用整數集合 intset 。首先看 intset 的數據結構: typedef struct intset {// 編碼方式uint32_t encoding;// 集合包含的元素數量…

vivo C/C++工程師 HR視頻面試問題總結20180807

一開始沒想到這次視頻面是HR面試,還以為是技術面試,畢竟上次面試的時候技術問題問的相對比較少,所以面試準備方向有點兒錯了,不過還是總結一下具體問題。 1)自我介紹:吸取了上次自我介紹的經驗,…

在Redis客戶端設置連接密碼 并演示密碼登錄

我們先連接到Redis服務 然后 我們要輸入 CONFIG SET requirepass “新密碼” 例如 CONFIG SET requirepass "A15167"這樣 密碼就被設置成立 A15167 我們 輸入 AUTH 密碼 例如 AUTH A15167這里 返回OK說明成功了 然后 我們退出在登錄就真的需要 redis-cli -h IP地…

redis源碼剖析(五)—— 字符串,列表,哈希,集合,有序集合

文章目錄對象REDIS_STRING (字符串)REDIS_LIST 列表REDIS_SET (集合)REDIS_ZSET (有序集合)REDIS_HASH (hash表)int refcount(引用計數器)unsigned lru:REDIS_LRU_BITS對象 對于 Re…

函數sscanf小結

1.sscanf用于處理固定格式的字符串&#xff0c;包含在頭文件<cstdio>中&#xff0c;函數原型為&#xff1a; int sscanf(const char *buffer,const char*format,[]argument ]...); 其中:buffer代表著要存儲的數據&#xff0c;format 代表格式控制字符串&#xff0c;arg…

redis源碼剖析(六)—— Redis 數據庫、鍵過期的實現

文章目錄數據庫的實現數據庫讀寫操作鍵的過期實現數據庫的實現 我們先看代碼 server.h/redisServer struct redisServer{...//保存 db 的數組redisDb *db;//db 的數量int dbnum;... }再看redisDb的代碼&#xff1a; typedef struct redisDb {dict *dict; /*…

多益網絡 視頻面試面試總結20180816

1.首先是自我介紹&#xff1a;因為等了半個小時&#xff0c;所以有點兒緊張&#xff0c;只說了一下自己的學校&#xff0c;愛好和興趣&#xff1b; 2.介紹了一個自己的最成功的項目&#xff1a;我介紹了一個關于GPS導航的項目&#xff0c;介紹了項目的內容和項目的一些工作&am…

redis源碼剖析(七)—— Redis 數據結構dict.c

文章目錄dict.hdict.cdict.h //定義錯誤相關的碼 #define DICT_OK 0 #define DICT_ERR 1//實際存放數據的地方 typedef struct dictEntry {void *key;void *val;struct dictEntry *next; } dictEntry;//哈希表的定義 typedef struct dict {//指向實際的哈希表記錄(用數組開鏈的…