Effective C++學習第五天

條款14:在資源管理類中小心copy行為

? ? ? ? ? 當我們深入理解“資源取得時機是初始化時機(RAII)”概念,并以此作為“資源管理類”的核心時,我們可能會遇到將RAII對象復制的情況,一般有兩種情況處理這個現象:1)如果我們的RAII對象是唯一的,那么復制就不合理,因此我們應該禁止copy構造的行為,正確的處理方式:將copy函數定義為private(base class),并用derived class private繼承這個函數來阻止copy行為;? 2)使用引用計數法,即智能指針的形式來實現對所有拷貝資源的追蹤,但是智能指針的缺省行為是當引用次數為0時刪除其所指向的對象。如果我們要實現的功能不是釋放資源,這時候就應該自定義智能指針的deleter(一個函數或者函數對象),當引用次數為0時調用這個函數實現相應功能,如:

class lock{

public:

? ? ? ? ?explicit lock(mutex *pm) : mutexptr(pm,unlock) { }? //用mutex初始化shared_ptr,并以unlock函數為刪除器

private:

? ? ? ? ? ? ? ? ?std::tr1::shared_ptr<mutex>mutexptr;

};

另外,上述例子中不需要聲明析構函數,因為class 析構函數會自動調用其non-static成員變量的析構函數;3)復制底部資源,采用深度拷貝的方法;4)采用轉移底部資源擁有權的方法,也就是所謂的auto_ptr指針;

條款15:在資源管理類中提供對原始資源的訪問

? ? ? ? ? 當你需要訪問一個RAII class對象的內部原始資源時,有兩種方法可以達成目標:1)在類的內部提供一個get成員函數,用來執行顯示轉換,也就是返回類內部指針的原始復件;2)允許隱式轉換到底部原始指針;在智能指針中,重載了指針取值操作符(operator->和operator*)來實現隱式轉換;對于一般的來說,可以在類中提供一個隱式轉換函數;如:

class font{

public:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //顯示轉換函數:

? ? ? ? ? ? explicit font(fonthandle fh) : f(fh){ }? ? ? ? ? ? ? ? fonthandle get() const {? ?return f;? }

? ? ? ? ? ? ~font() { releasefont(f); }? ? ? ? ? ? ? ? ? ? ? ? ? ? //隱式轉換函數??

private:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?operator fonthandle() const {return f;}//沒太明白怎么隱式轉換的

? ? ? ? ? fonthandle f;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //operator起到什么作用?

}

//顯示轉換? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//隱式轉換

void changefontsize(fonthandle f,int newsize);? ? ? ? ??void changefontsize(fonthandle f,int newsize);

font f(getfont());? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?font f(getfont());

changefontsize ( f.get(), newfontsize);? ? ? ? ? ? ? ? ? ? ??changefontsize ( f, newfontsize);

//但隱式轉換會出一個問題

font f1(getfont());? ??

fonthandle f2=f1;? ?//原意是拷貝,結果是f1先轉化為底部的fonthandle,然后拷貝,一旦此時f1被銷毀,f2就處于指向資源被釋放的狀態(dangle)

條款16:成對使用new和delete時采取相同的方式

? ? ? ? ? ? ? ?如果你在new的表達式中使用[ ],則必須在相應的delete表達式中也使用[ ],如果沒有使用[ ],那么也一定不要在delete中使用[ ];

條款17:以單獨語句將newed對象置入智能指針中

? ? ? ? ? 對于以下代碼分析;

? ? ? ? ? ? int priority( );

? ? ? ? ? ?void processwidget(std :: tr1 :: shared_ptr<wideget>pw,int priority);

? ? ? ? ? ? //調用時? ?processwidget(new widget, priority( ));//編譯錯誤,shared_ptr構造函數是explicit類型,不允許隱式轉換

? ? ? ? ? ?//processwidget(std :: tr1 ::?shared_ptr<wideget>(new widget),priority( ) );

? ? ? ? ? ?這個函數在調用processwidget之前,編譯器必須創建代碼,完成以下三件事情:1)調用priority;2)執行new widget;3)調用 std::tr1::shared_ptr構造函數;但是1)和2)的執行順序和編譯器有關,如果先執行2)后執行1),且在執行1)的時候發生異常,那么new widget返回的指針就會失效,那么內存泄露就產生了;

? ? ? ? ? 解決上述問題的方法:使用分離語句,把創建對象和給智能指針賦初值的語句分離出來,原因是:編譯器對于“跨越語句的各項操作”沒有重新排列的自由(只有在語句內才擁有那個自由度);代碼如下:

? ? ? ? ?std::tr1::shared_ptr<widget>pw(new widget);

? ? ? ? ? processwidget(pw,priority( ));

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

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

相關文章

Redis運維和開發學習筆記(2) redis持久化

Redis運維和開發學習筆記(2) redis持久化 文章目錄Redis運維和開發學習筆記(2) redis持久化持久化持久化方式一:RDB觸發~~的三種~~方式1. save命令2. bgsave配置觸發機制RDB 總結持久化方式二:AOFAOF的三種策略三種策略的優缺點AOF重寫機制持久化 redis將所有數據保存在內存中&…

Effective C++學習第六天

條款18&#xff1a;讓接口更容易被正確使用&#xff0c;不易被誤用設計接口的原則&#xff1a;正確性、高效性、封裝性、維護性、延展性以及協議的一致性&#xff1b;設計原則&#xff1a;1&#xff09;導入新類型來預防很多客戶端的錯誤&#xff0c;多使用系統類型&#xff08…

Redis運維和開發學習筆記(4) Redis參數意義

Redis運維和開發學習筆記(4) Redis參數意義 文章目錄Redis運維和開發學習筆記(4) Redis參數意義參數意義參數意義 Client連接 問題 id567800790 addr10.18.17.217:37310 fd1572 name age2039114 idle2034860 flagsN db0 sub0 psub0 multi-1 qbuf0 qbuf-free0 obl0 oll0 omem0 …

Effective C++學習第七天

條款23&#xff1a;寧以non-memeber、non-friend替換member函數non-member/non-friend可以給對象帶來更大的封裝性&#xff0c;從兩個方面來考慮&#xff1a;1&#xff09;考慮封裝&#xff0c;越多東西被封裝&#xff0c;它們就越不可見&#xff0c;就越少人看到它&#xff0c…

Redis運維和開發學習筆記(5) 主從復制和sentinel哨兵模式

Redis運維和開發學習筆記(5) 主從復制和sentinel哨兵模式 主從復制 將主節點的數據改變同步給從節點 作用 備份數據讀寫分離 存在的問題&#xff1a; 手動干預切主等操作主節點的寫能力受到單機限制主節點的存儲能力受到單機限制 主從模式的故障恢復 當主節點發生故障時&am…

Effective C++學習第八天

條款26&#xff1a;盡可能延后變量定義式的出現時間當你定義了一個變量&#xff0c;如果在使用變量之前出現異常&#xff0c;那么你得承受一次構造成本和析構成本&#xff0c;而且你沒有使用該變量&#xff1b;本條款給出的建議是延遲變量的定義&#xff0c;直到非得使用該變量…

Redis運維和開發學習筆記(6) 監控Redis工作狀態-info命令

Redis運維和開發學習筆記(6) 監控Redis工作狀態-info命令 文章目錄Redis運維和開發學習筆記(6) 監控Redis工作狀態-info命令info serverinfo clientinfo memoryinfo persistenceinfo statsinfo commandstatsinfo cpuinfo clusterinfo keyspaceinfo server Redis服務器相關的通用…

Effective C++學習第九天

條款32&#xff1a;確定你的public繼承塑模出is-a模型class D&#xff08;derived&#xff09;以public形式繼承class B&#xff08;base&#xff09;&#xff0c;則每一個類型為D的對象同時也是一個類型為B的對象&#xff0c;反之不成立&#xff0c;因此B比D表現出更加一般化的…

Effective C++學習第十天

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

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

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

Effective C++學習第十一天

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

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

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

Effective C++學習第十二天

條款47&#xff1a;請使用traits classes表現類型信息STL有五類迭代器分類&#xff0c;input迭代器&#xff08;只讀&#xff0c;一次&#xff0c;向前&#xff09;、output迭代器&#xff08;可寫&#xff0c;一次&#xff0c;向前&#xff09;、forward迭代器&#xff08;讀/…

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

Redis源碼分析&#xff08;一&#xff09;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文本命令行語言環境設置命令 查看當前語言環境&#xff1a; echo &#xffe5;LANG 修改&#xff1a; LANG選擇的語言環境’ 引申&#xff1a;https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬鏈接和軟連接 linux中文件的儲存方式&#xf…

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

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

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

文章目錄1. int main()2. parseOptions(int argc, char **argv) 進行ip和port的改變3. lookupCommand(char *name) 查找命令&#xff0c;判斷命令合法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中定義的數據類型&#xff1a; C語言中定義了6種基本數據類型&#xff1a;short,int,long,float,double,char 4種構造類型&#xff1a;數組&#xff0c;結構體&#xff08;struct&#xff09;&#xff0c;共用類型(union)&#xff0c;枚舉類型(enum) 指針類型和空類型 C語…

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

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

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

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