Effective C++學習第二天

1:確保對象被使用前已先被初始化,讀取未初始化的值會造成不明確的行為,可能導致程序終止運行或者其他不可預期的現象;在C++中,當你使用C part of C++(C++中C語言部分的內容)且初始化可能導致運行期成本,那么就不會保證一定初始化,而non-C part of C++,系統卻能保證被初始化。對于內置類型(C++定義算術類型(整型和浮點型)和空類型為內置類型),需要手動完成初始化;對于自定義類型,需要用構造函數完成相應的初始化工作;

2:區分賦值(assignment)操作和初始化(initialization)的行為,在實現相同功能的情況下盡可能的使用初始化的方式

? ? ? 對象成員的初始化動作發生在進入構造函數之前,進入構造函數本體之前,成員變量自動調用自己的default構造函數完成默認初始化(不使用初始化列表的情況下),然后進入函數體執行對應的功能;

? ? ? 針對上述情況,使用成員初始化列表(member initialization list)替換常規的賦值操作可以省去一個賦值操作的過程,直接實現以各個成員變量的實參拷貝構造給形參,初始化列表中應包含所有的成員變量;

? ? ? 對于大多數類型而言,比起先調用default構造函數后調用copy assignment操作符,只調用一次copy構造函數是比較高效的,但對于內置類型,其初始化和賦值的成本相同,但為了一致性效果,都采用初值化列表的形式;

? ? ? 如果成員變量是const或者references,那么就一定需要初值,而不能被賦值

? ? ? 初始化列表的初始化順序是按照成員變量的定義順序進行初始化的,與初始化列表中變量如何排列無關;

? ? 結論:初始化時,使用初始化列表可以使你的程序更加高效;當我們想要用default構造成員變量的時候,我們也可以指定成員初始列,只要指定初始化實參為空就行;

3:當classes中有多個構造函數時,每個構造函數有自己的成員初始列,那么這樣就可能出現重復的初值列,這種情況下可以將初始值列中那些“賦值表現像初始化一樣好”的成員變量,改用它們的賦值操作,并把這些賦值操作合并成一個函數(通常是private)來供所有的構造函數使用;

4:static對象,其壽命從被構造出來到程序結束為止。通常函數內的static對象稱為local static對象,其他的static對象稱為non-local static對象;

? ? ? 問題:當某個編譯單元內的某個非non-local static對象的初始化動作使用了另一個單元內的的某個non-local static對象,可能所用到的這個對象可能沒有初始化,而且C++對這個初始化的順序沒有明確的定義;

? ? ?解決方法:采用singleton設計模式,將每個non-local static對象搬到自己的專屬函數內(該對象在函數內被聲明為static),然后然后函數返回一個引用指向這個static對象,然后使用者調用這些函數,而不直接去指涉這些對象。這個方法的好處在于:C++保證了在函數內的local static對象會在“這個函數調用期間”“首次遇上該對象定義式時”被初始化;代碼如下:

class filesystem

{

public:std:size_t numberdisks() const;

};

extern filesystem tfs;//修改為filesystem&? tfs(){staticfilesystem fs;return fs;}

class directory

{

public:directory(params) {std::size_t disks=tfs.numberdisks();//修改為? std::size_t disks=tfs().numberdisks;

};

directory tempdir(params);//修改為directory& tempdir() {static directory td; return td;}

? ? ? 修改之后,程序用戶完全和以前一樣使用,唯一不同的就是使用函數返回的是指向static對象的引用,而非static對象本身;

? ? ? 對于singleton模式下的reference-returning函數比較簡單,往往可以變成inline函數,但是對于多線程環境下會帶來很大的麻煩;

? ? ? 引申:編譯單元是指產生單一目標文件的那些源碼,基本上它是單一源碼文件加上其所包含的頭文件,平常寫程序的一個文檔就稱為一個編譯單元;

? ? ? 結論:為了避免在對象初始化之前使用對象,需要做三件事情:1)手工初始化內置類型non-number對象;2)使用成員初始值列表對方對象的所有成分;3)在初始化次序不確定的情況下可以考慮singleton設計模式,也就是在處理跨編譯單元的初始化次序時,用local static對象替換non-local static對象。

5:如果自己沒有聲明類中的函數,編譯器會自動生成一個default構造函數、一個copy構造函數、一個copy assignment操作符和一個析構函數(non-virtual),并且這些函數都是public和inline的;

? ? ?編譯器生成的copy構造函數和copy assignment操作符只是單純地將來源對象的每一個non-static成員變量拷貝給目標對象;

? ? ?如果自己聲明了一個構造函數,則編譯器不再提供default構造函數;

? ? ?編譯器生成的copy assignment操作符,行為和copy構造函數一樣,當且僅當生成的代碼合法且有意義時;否則編譯器拒絕為class生成operator=,如成員變量中含有引用或者const變量時,則編譯器不能為自動生成一個copy assignment操作符;

? ? ?編譯器拒絕自動生成一個copy assignment構造函數的情況:1)內含reference成員變量;2)內含const變量;3)在base classes將copy assignment操作符聲明為private;編譯器拒絕為derive classes生成一個copy assignment操作符;

6:如果想要阻止某些函數被創建出來,聲明這個函數,并將其權限設置為private,但是member函數和friend函數還是可以調用private函數;

? ? ? ? ?阻值member或者friend函數調用的方法,利用一個base class,將需要阻止的函數(private權限)放到base class內,我們所需要做的就是(private)繼承base class;當我們的類要生成copy構造函數和copy assignment函數時,會調用base class類中的對應函數,這些調用會被編譯器拒絕,因為函數的權限是private;

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

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

相關文章

Redis運維和開發學習筆記(3)redis搭建集群

Redis運維和開發學習筆記(3)redis搭建集群 文章目錄Redis運維和開發學習筆記(3)redis搭建集群Redis集群搭建Redis集群搭建 cp /etc/redis.d/redistest_7001.conf /etc/redis.d/redistest_XXXX.conf :%s/7001/xxxx/g 配置文件內容:cluster-enabled yes ############…

Effective C++學習第三天

1:為多態基類聲明virtual析構函數當我們創建一個base class指針指向新生成的derived class時,當刪除基類指針時,如果base class是一個non-virtual析構函數時,實際執行的結果通常是derived class中的base成分被銷毀,der…

linux創建指定大小的文件

一、生成文件大小和實際占空間大小一樣的文件 dd if/dev/zero ofname.file bs1M count1 文件名稱name.file bs1M表示每一次讀寫1M數據,count50表示讀寫 50次,這樣就指定了生成文件的大小為50M。 二、生成文件大小固定,但實際不占空間命令 …

Effective C++學習第四天

條款11:在operator中處理自我賦值的現象雖然我們在平時可能不會出現顯示自我賦值的現象,當加入指針或者引用時,可能會出現不同的指針或引用指向同一對象(對象的不同別名),這時候我們就得考慮對象是否是同一…

Effective C++學習第五天

條款14:在資源管理類中小心copy行為當我們深入理解“資源取得時機是初始化時機(RAII)”概念,并以此作為“資源管理類”的核心時,我們可能會遇到將RAII對象復制的情況,一般有兩種情況處理這個現象&#xff1…

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

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

Effective C++學習第六天

條款18:讓接口更容易被正確使用,不易被誤用設計接口的原則:正確性、高效性、封裝性、維護性、延展性以及協議的一致性;設計原則:1)導入新類型來預防很多客戶端的錯誤,多使用系統類型&#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:寧以non-memeber、non-friend替換member函數non-member/non-friend可以給對象帶來更大的封裝性,從兩個方面來考慮:1)考慮封裝,越多東西被封裝,它們就越不可見,就越少人看到它&#xff0c…

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

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

Effective C++學習第八天

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

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:確定你的public繼承塑模出is-a模型class D(derived)以public形式繼承class B(base),則每一個類型為D的對象同時也是一個類型為B的對象,反之不成立,因此B比D表現出更加一般化的…

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…