Effective C++學習第十天

條款36:絕不重新定義繼承而來的non-virtual函數

? ? ? ? ? non-virtual函數執行的是靜態綁定,在編譯器就已經決定,因此對象對用的函數只和指針的類型有關,而與指針所指的對象無關;記住non-virtual函數的性質:不變性凌駕于特異性;

條款37:絕不重新定義繼承而來的缺省參數值

? ? ? ? ?靜態類型是指在程序中聲明時使用的類型,動態類型是指目前所指對象的類型,動態類型變現為一個對象將會有什么樣的行為;

? ? ? non-virtual和參數缺省值執行的是靜態綁定,virtual執行的是動態綁定,代碼分析:

class shape{

public:

? ?enum shapecolor { red, green, blue };

? virtual void draw(shapecolor color=red) const=0;

};

class rectangle:public shape{

public:

? ? ? ? ? virtual void draw(shapecolor color=green) const;//糟糕的操作

? ? ? ? ?...

}

class circle:public shape{

public:

? ? ? ? ? ? ? virtual void draw(shapecolor color)const;

? ? ? ? ? ? ? ...

};

調用 shape *pr=new rectangle;

? ? ? ? pr->draw( );//執行的代碼為rectangle::draw(shape::red):

? ? ? ? ? ? ? ? ? ? ? ? ? //相當于shape執行缺省,rectangle執行virtual函數,一人一半,神奇的操作;

C++這樣設計的原因:運行期效率,如果缺省值是動態綁定,編譯器就必須用某種方法在運行期為virtual函數決定適當的參數缺省值,這比目前實現的在編譯期決定的機制更慢更加復雜;

條款38:通過復合塑模出has-a或者根據某物實現出

? ? ? ? ? 復合是類型之間的一種關系,當某種類型的對象內含它種類型的對象,就是這種關系;復合有兩種意義,復合意味著has-a(有一個)或is-implemented-in-terms-of(根據某物實現出);

? ? ? ? ?如何區分is-a(是一種)和is-implemented-in-terms-of(根據某物實現出)這兩種關系,可以通過public繼承中D繼承B,D對象也是B對象,反之B對象不是D對象來判斷;

條款39:明智而審慎地使用private繼承

? ? ? ? ? private繼承意味著implemented-in-terms-of(復合),它只有實現部分被繼承,接口部分省略;private繼承純粹是一種實現技術,它在軟件設計層面上沒有意義,其意義只及于軟件實現層面;代碼分析:

? ? ? class person {...};

? ? ? class student:private person{ . . .};

? ? ? void eat(const person&p);

? ? ? person p;??? student s;? ??? eat(p);

? ? ? eat(s);//編譯不通過

原因:1)private繼承中編譯器不會自動將一個derived class對象轉換為一個base class對象;2)private繼承而來的所有成員在derived? class中都會變成private屬性,縱使它們在base class中原本是public或者protected;? ?

? ? ? ?盡可能的多用復合,必要的時候才使用private繼承(protected成員和virtual函數牽涉進來的時候,或者繼承一個empty class時候可以采用private繼承)

? ? ? ?需求:定義一個類B(繼承一個類B_B),使得這個類的派生D不能調用B_B的成員函數;

設計1:private繼承

class B_B{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?class D:private B_B{

public:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?private:?

? ? ? ?explicit B_B(int tickfrency);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? virtual void ontick( ) const;

? ? ? ?virtual void ontick( )const;

};? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };

設計2:繼承+復合

class D{

private:

? ? ? ? class widgettimer:public B_B{

? ? ? ? ?public:? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ?virtual void ontick( )const;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...

? ? ? ? };

? ? widgwttimer timer;

}

在D內聲明一個嵌套式private class,后者以public繼承B_B并重新定義ontick,然后放這個類型在D對象內;

選擇方案2不選擇方案1的原因:1)想阻止D的derived class重新定義ontick函數;2)降低D編譯的依存性;

? ? ? ? ? empty class:沒有non_static成員變量,沒有virtual函數,沒有virtual base class;empty class數據大小并不是零,C++規定凡是獨立對象都必須有非零大小(這個約束不針對derived class 中的base class成分,它們是非獨立的),因此一個empty class 大小為1(C++規定安插一個char類型到空對象中);

? ? ? ? ?在繼承empty class中,如果選擇private繼承(EBO,empty base optimization,繼承空類),可能造成empty base的最優化;

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

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

相關文章

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 {//指向實際的哈希表記錄(用數組開鏈的…

簡述linux中動態庫和靜態庫的制作調用流程

假設現在有這些文件&#xff1a;sub.c add.c div.c mul.c mainc head.h&#xff08;前4個.C文件的頭文件&#xff09; 1.靜態庫制作流程 gcc -c sub.c add.c div.c mul.c -->生成 .o目標文件文件 ar rcs libmycal.a *.o …