亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

Effective C++學習筆記

2019-11-06 06:44:02
字體:
來源:轉載
供稿:網友

總結: 囫圇吞棗地看完了EffectiveC++這本書,收獲不少。收獲主要是以下幾個方面:

編程注意細節 提高程序效率的細節比如constis-a 和 has-a的區別pure-virtual、impure-virtual和non-virtual之間繼承該如何處理繼承中隱藏基類的成員等設計方法 什么時候該繼承(is-a),什么時候該以對象作為data member(is-inplemented-in-terms-of);Template method、 Strategy, 抽象工廠等設計模式泛型編程與模板編程異常安全性 異常處理copy-swap技術

由于沒有太多的實戰經歷,所以有些東西并不是很懂。 所幸在看書過程中,做過一些筆記整理,其中 大部分內容摘抄自書上,一小部分加上自己的一點點理解,方便日后回顧。

02: 對于單純常量,最好以const對象或 enums 替換#define

03: 盡可能使用const

mutable 關鍵字表征 const成員函數可以修改mutable成員

04: 為內置對象進行手工初始化,C++并不保證初始化他們;

05: 在類中,如果有引用 或const對象,記得要自己編寫構造函數,拷貝構造函數等,因為編譯器自己生成的相關函數很大可能達不到要求。

06: 為了駁回編譯器自動提供的功能(構造函數,拷貝等),可以將相應的member function declared PRivate,并且不予實現; 或者使用像Uncopyable這樣的base class;

07: 當類作為基類的時候,有可能表現出多態的時候,應將虛構函數設計成virtual

09: 絕不在構造函數和析構函數中調用virtual function; 如果在base class 調用了virtual function,在派生類的構造函數初始化基類的時候,實際上還是調用的是base class的function,并沒有調用dervied class的內容(此時derived class 并沒有完成初始化)

10: 令 Operator= 返回一個referece to *this (方便連續賦值 如 a = b = c;);

11: 在operator=中處理“自我賦值”copy and swap 技術實現自我賦值;

class Widgt {void swap(Widgt& rhs);// 交換*this 和 rhs的數據}Widget& Widget::operator=(const Widget& rhs) { Widget tmp(rhs); swap(rhs); return *this;}

12: 復制對象的時候務必記住每一個成員 copying函數應該確保復制“對象內的所有成員變量” 以及“所有base Class 的成分”

13: 以對象管理資源 記得用智能指針管理資源;

14: 在資源管理類中心小心copying行為

當資源管理類需要copy的時候 需要從以下幾個方面考慮 禁止復制(將拷貝構造函數,以及拷貝賦值函數 設置于private有點類似于unique_ptr<>)對底層資源使用“引用計數法” 模仿“shared_ptr”復制底部資源(深拷貝,每一份對象都有自己的heap內存)轉移資源的管理權(有點像 auto_ptr )

15: 資源管理類中需要提供對原始資源的訪問

智能指針類可以隱式轉化為底部的原始指針,便于訪問底部的成員可以有顯式轉換(較為安全)和隱式轉換(對客戶比較安全)

16: 成對使用new 和delete 尤其注意在利用typedef中聲明新的類型名時(盡量少用typedef聲明數組類型)

17: 以獨立語句將new出來的對象置入智能指針

Design and Declarations

18: make interfaces easy to use correctly and hard to use incorrectly 令自己的types和內置types的行為一致 盡量保持接口一致性 如STL容器的接口 19: Treat class design as type design type的對象應該如何該創建和銷毀;對象的初始化和賦值該有什么樣的區別新type的對象如果pass by value 意味著什么新type的合法值 ?哪些賦值是合法的是否需要配合某個繼承圖系(inheritance graph)嗎?什么樣的類型轉換?什么樣的操作符和函數對此新type而言是合理的?(設計接口)什么樣的標準函數應該被駁回?(設計為private)誰該取用新type的成員? (設計為public)20: 以pass-by-reference to const 替換pass-by-value 前者比較高效,同時可以避免切割問題;對于內置類型、STL的迭代器和函數對象。 對他們而言,pass-by-value往往比較合適21: Don’t try to return a reference when you must return an object; 絕對不要返回pointer或reference指向一個local stack對象(會產生未定義的行為)絕對不要返回指向一個heap-allocated對象(無法控制對象的銷毀)絕對不要返回pointer或reference指向一個local static對象(可能需要多個這樣的對象)(在多線程情況下也難以保證安全)22: Declare data members private 可以實現對data member的各種權限控制有利于封裝,注意protected 并不比public更具有封裝性23: Prefer non-member non-friend替換member函數 其實是具有更大的封裝性(注意namespace)增加封裝性,packaging flexibility 和機能擴充性24: 若所有參數需要類型轉換,請將此函數設計成non-member函數 有理數類(Rational)的的四則運算; Rational tmp = Rational() * 2 ; Rational tmp = 2 * Rational(); 考慮這兩種情況

25 : Consider support for a non-throwing swap( 不拋異常)

缺省版本swap

如果缺省版本的效率不夠,可以嘗試做

提供一個public swap函數(這個函數,不要拋出異常)在class 或template所在的命名空間內提供一個non-member swap,并調用上述的swap成員函數如果正編寫一個class(非template),需要特化std::swap, 并令他調用你的成員swap

注意: 不要忘std里加入任何新的東西

// default swaptemplate <typename T>void swap(T& a, T& b){ T temp(a); a = b; b = tmp;}class Widget { public: void swap(Widget &other);}26: 盡可能延后變量定義式的出現的時間(用到的時候才再去聲明) 循環里用到的變量盡量在循環里聲明,除非 賦值成本比構造加析構低,處理代碼中效率高度敏感的部分

27: 盡量少做轉型動作(如果轉型必要,就封裝在函數里面)(新式轉型 好于 舊式轉型)

const_castdynamic_caststatic_cast reinterpret_cast 不適合移植

28: Avoid returning “handles”to object internals

handles (pointer, reference, iterators)

29: Strive for exception safety code(為異常安全性努力是值得的)

帶有異常安全性的函數會: 不泄露任何資源不允許數據敗壞

異常安全函數(Exception-safe code)提供下面三個保證之一

基本承諾

程序內的任何事物都保持在有效狀態下(對象或者數據結構不會有因此而損壞)當異常時,可以選用默認狀態,也可以回復到變換之前的狀態

強烈保證(往往以copy-and-swap實現出來)

函數成功,就完全成功,如果失敗,程序會回復到調用函數之前的狀態nothrow 保證

30: Understand the ins and outs of inlining

virtual 和inline同時出現,編譯器往往會拒絕inlineinline限制在小型、頻繁調用的函數身上構造函數最好不要inline

31: 將文件間的編譯依存關系降至最低

接口與實現的分離 如果使用object reference 或者 object pointers可以完成任務,就不要使用objects如果能夠,盡量以class聲明式替換定義式為聲明式和定義式提供不同的頭文件

32: 確定public繼承是is-a的關系(注意區分has-a)

適用于derived class身上的所有事情都能適用于base class身上

33: Avoid hiding inherited names(避免隱藏繼承的成員名)

避免隱藏基類的成員名 可以使用using 聲明式或者 forwarding function

34: Differentiate between inheritance of interface and inheritance of implementation(區分接口繼承和實現繼承)

pure virtual: 為了讓derived class繼承函數接口(繼承了的具象類都要重新聲明)impure virtual: 繼承該函數的接口和缺省實現non-virtual:為了令derived classes繼承函數的接口及一份強制性實現

35: 考慮virtual函數以外的其他設計方式(提及設計模式中的Template Method 和 Strategy)

令客戶通過public non-virtual成員函數間接調用private函數(NVI手法)/// Template Methodclass GameCharacter {public: int healthValue() const { ··· // 做一些事前工作 int retVal = doHealthValue(); ··· //做一些事后工作 return value; } ···private: virtual int doHealthValue() const { ··· // 缺省算法,計算健康指數 } }借由function pointers實現strategy模式class GameCharacter;int defaultHealthCalc(const GameCharacter& gc);class GameCharacter {public: typedef std::function<int (const GameCharacter&)> HealthCalcFunc; explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) : healthFunc(hcf) {} int healthValue() const { return healthFunc(*this);}private: HealthCalcFunc healthFunc;};/// 可以轉換成function對象short calcHealth(const GameCharacter&); // 返回類型 non-intstruct HealthCalculator { //為計算健康值設計的函數對象 int operator()(const GameCharacter&) const {···}};class GameLevel {public: float health(const GameCharacter&) const; // 成員函數 ···};使用non-virtual interface手法,那是Template Method設計模式的一種特殊形式,它以public non-virtual成員函數包裹性較低訪問性(private或protected)的virtual函數將virtual函數替換為“函數指針成員變量”,這是strategy設計模式的一種分解表現形式以function成員變量替換virtual函數, 因此允許使用任何可以轉變成(callable entity)function對象的表達式,也是strategy的一種表現形式

36: Never redefine an inherited non-virtual function.

如果重新定義從基類繼承的non-virtual function, 那么就應該是設計出現了問題

37: 絕不重新定義繼承而來的缺省參數值(針對virtual函數)

virtual函數系動態綁定,而缺省參數值卻是靜態綁定如果需要缺省值,應該將該函數設計為non-virtual函數,再設計一個private的virtual function 如同前面介紹的Template Method設計

38: Model “has-a”or “is-implementated-in-terms-of” through composition

在應用域內,是has-a的關系在實現域中,是根據某物實現出 例如STL庫中的stack是以vector為底層數據結構實現的

39: 明智而謹慎地使用private繼承

private繼承某種意義上說 is-implemented-in-terms-of, 所以盡可能使用38條中使用復合的方式實現除非確定private繼承可以造成empty base最優化

40: 明智而謹慎地使用多重繼承

多重繼承比單一繼承復雜;以及可能會對virtual繼承的需要virtual繼承會增加大小,速度,初始化復雜度等成本

模板與泛型編程

41: 了解隱式接口和編譯器多態

以不同的template參數具現化function templates會導致調用不同的函數,這就是編譯期多態(有點像重載函數) classes 和 templates都支持接口(interface)和多態(polymorphism)對classes而言接口是顯式的,以函數簽名為中心。多態則是通過virtual函數發生于運行期對template參數而言,接口是隱式(implicit)的,奠基于有效表達式;多態則是通過template具現化發生于編譯期

42: 了解typename的雙重意義

聲明template參數時,class和typename可以互換記得使用typename標識嵌套從屬類型名稱;但不要在base class List或 member initialization list內以它作為base class的修飾符

43: 學習處理模板化基類內的名稱

繼承模板基類的時候,基類的成員函數不可見;這個時候可以用一下三種方式解決 在前面添加this指針利用using語句,使模板基類的函數可見利用基類的類名加::調用基類函數

44: 將與參數無關的代碼抽離template

template生成多個classes和多個function,所以任何template代碼都不該與某個造成膨脹(怎么造成代碼膨脹呢?)的template參數產生相依關系因非類型模板參數而造成的代碼膨脹,往往可以消除,做法是以函數參數或class成員變量替換template參數因類型參數(type parameters)而造成的代碼膨脹,往往可以降低,做法是讓帶有王權相同的二進制表述的instantiation types共享實現碼

45: 運用成員函數模板接受所有的兼容類型

請使用member function templates生成“可接受所有兼容類型”的函數如果你聲明member templates 用于“泛化copy構造”或泛化assignment操作,還是需要聲明正常的拷貝構造函數和copy assignment操作符46: 需要類型轉換時請為模板定義非成員函數 編寫class template,需要支持與此template相關函數 支持參數之隱式類型轉換 時,請將那些函數定義為 class template內部的friend函數

47: 請使用traits classes表現類型信息

Trait classes使得“類型相關信息”在編譯器可以用,以template特化實現整合overloading技術

48: 認識template元編程

49: 了解new-handler的行為

new-handler函數要完成以下的事情:

讓更多內存可被使用安裝另一個new-handler(令new-handler修改會影響new-handler行為的static數據,global數據)卸除new-handler(將null指針傳遞給set_new_handler)跑出bad_alloc(或派生出來的)異常

Nothrow new是一個頗為局限的工具,因為它只適用于內存分配 夠來的構造函數還是可能跑出異常

50: 了解new和delete的合理替換時機

51: 編寫new和delete時需要固守常規

52: 寫了placement new也要寫placement delete(不熟悉)

53: pay attention to compiler warnings

編譯器的警告能力是不一樣的; 編寫程序,爭取完全無警告

54: 讓自己熟悉TR1在內的標準程序庫(現在C++11基本都實現了)

55: 讓自己熟悉boost程序庫(泛型編程, 模板元編程)

沒有理解和不太懂的地方,也有幾處,主要集中于:

泛型編程模板元編程trait type、trait class, 特化以及偏特化

接下來的學習之路也需要偏重以下上述方面。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品99久久久久久久久| 日韩在线视频播放| 少妇激情综合网| 久久激情视频久久| 有码中文亚洲精品| 成人性生交大片免费观看嘿嘿视频| 日韩视频在线一区| 国产欧美精品在线| 色综久久综合桃花网| 日本国产一区二区三区| 亚洲国产日韩欧美在线图片| 色777狠狠综合秋免鲁丝| 久久色免费在线视频| 日韩欧美高清视频| 91日韩在线播放| 欧美伊久线香蕉线新在线| 亚洲欧美资源在线| 国产一区二区免费| 亚洲自拍av在线| 国产精品中文字幕在线观看| 欧美激情videos| 亚洲无限乱码一二三四麻| 欧美亚洲在线观看| 久久福利视频网| 亚洲国产欧美在线成人app| 国产suv精品一区二区| 国产精品自产拍高潮在线观看| 尤物九九久久国产精品的特点| 国产香蕉精品视频一区二区三区| 国产在线98福利播放视频| 亚洲高清一区二| 久久久久久久久久久久久久久久久久av| 精品久久久精品| 久久精品国产2020观看福利| 九九精品在线视频| 成人黄色午夜影院| 亚洲第一中文字幕在线观看| 国产999精品| 亚洲一区二区自拍| 欧美黑人一级爽快片淫片高清| 欧美国产精品日韩| 91精品久久久久久久久中文字幕| 91中文在线观看| 精品亚洲永久免费精品| 国模精品一区二区三区色天香| 欧美电影《睫毛膏》| 57pao成人永久免费视频| 日韩av第一页| 亚洲一区二区久久| 欧美一级bbbbb性bbbb喷潮片| 久久五月情影视| 久久人体大胆视频| 日韩av在线天堂网| 国产成人精品久久亚洲高清不卡| 久久综合网hezyo| 国产在线视频2019最新视频| 亚洲欧美另类人妖| 欧美日韩第一页| 夜夜躁日日躁狠狠久久88av| 亚洲人成自拍网站| www.亚洲免费视频| 亚洲国产精品久久久久| 国内外成人免费激情在线视频| 日韩精品在线观看网站| 亚洲精品永久免费| 成人免费视频网| 日韩av在线天堂网| 国产成人久久久精品一区| 91产国在线观看动作片喷水| 美日韩丰满少妇在线观看| 日韩精品亚洲精品| 欧美日韩视频在线| xxxxxxxxx欧美| 亚洲国产精品嫩草影院久久| 久久久久久久国产精品| 国产美女久久精品香蕉69| 欧美一区二区三区精品电影| 亚洲精品美女久久久久| 亚洲精品网站在线播放gif| 成人动漫网站在线观看| 91在线观看免费高清| 一本色道久久88综合亚洲精品ⅰ| 成人精品久久av网站| 午夜精品一区二区三区av| 日韩va亚洲va欧洲va国产| 最好看的2019年中文视频| 精品久久久一区二区| 91禁外国网站| 欧美噜噜久久久xxx| 国产精品69久久| 精品福利樱桃av导航| 精品自拍视频在线观看| 91免费视频国产| 久久精品福利视频| 亚洲国产高清高潮精品美女| 日韩精品免费看| 亚洲一区二区三区四区视频| 国产激情视频一区| 精品无人区乱码1区2区3区在线| 国产乱人伦真实精品视频| 成人观看高清在线观看免费| 精品国产老师黑色丝袜高跟鞋| 亚洲国产精品女人久久久| 欧美精品一区在线播放| 国产在线视频欧美| 国产精品羞羞答答| 日韩av电影国产| 九九精品视频在线| 日本亚洲精品在线观看| 欧美大尺度电影在线观看| 伊人久久精品视频| 成人国产精品久久久| 成人黄色网免费| 久久天天躁狠狠躁夜夜躁| 久久久免费高清电视剧观看| 亚洲图片欧美午夜| 国产91精品视频在线观看| 亚洲一区二区三| 日本不卡高字幕在线2019| 久久中文久久字幕| 久久精品视频亚洲| 国产美女搞久久| 久久久久久亚洲精品中文字幕| 日韩av影视综合网| 亚洲欧美另类中文字幕| 成人福利免费观看| 九九热在线精品视频| 欧美性猛交xxxx黑人| 久久精品久久久久| 欧美第一黄网免费网站| 色婷婷av一区二区三区在线观看| 91大神福利视频在线| 91久久久在线| 高潮白浆女日韩av免费看| 青青草99啪国产免费| 青青青国产精品一区二区| 久久韩国免费视频| 精品中文字幕在线| 亚洲无av在线中文字幕| 日韩成人免费视频| 宅男66日本亚洲欧美视频| 午夜剧场成人观在线视频免费观看| 亚洲精品久久7777777| 国产亚洲成av人片在线观看桃| 爽爽爽爽爽爽爽成人免费观看| 国产精品h片在线播放| 伊人一区二区三区久久精品| 国产亚洲视频在线观看| 日本欧美精品在线| 久久久久久久久久国产| 亚洲午夜小视频| 成人av在线亚洲| 中文字幕日韩在线播放| 日韩av网站导航| 国产成人精品日本亚洲专区61| 国产精品国产福利国产秒拍| 久久精品91久久久久久再现| 国产欧美一区二区三区久久| 国产日韩精品在线播放| 亚洲精品久久久久中文字幕欢迎你| 亚洲精品视频二区| 久久精品成人动漫| 国内揄拍国内精品| 91啪国产在线|