C 高階筆記之一 儲存之廚

2022-09-22 23:57:12 字數 1636 閱讀 1180

優化相關

使用靈活的、動態分配的資料,不要使用固定大小多陣列;

優先使用線性演算法或者盡可能快的演算法:

push_back 雜湊表查詢:o(1)

set/map lower_bound/upper_bound: o(logn)

vector::insert for_each o(n)

盡可能避免劣於線性複雜性的演算法,永遠不要使用指數複雜性的演算法;

不要進行不成熟的優化:

可以用通過引用傳遞的時候,卻定義了通過值傳遞的方式傳遞引數;

可以使用字首++、--運算的時候,卻使用了字尾的方式;

建構函式中使用賦值操作而非初始化列表

併發程式設計

儘量減少全域性和共享資料避免使用名字空間作用域中具有外部連線的資料或者作為靜態類成員的資料。如果不得不用,一定要對其仔細進行初始化。在不同編譯單位中這種物件的初始化順序是未定義的,為此需要高度注意;另外,名字空間作用域中的物件、靜態資料成員物件或者跨執行緒(程序)共享的物件會減少並行性,往往是產生效能和可伸縮性瓶勁的原因。

例外情況: cin/cout/cerr 比較特殊: cout << "hello world" 等價於(cout, "hello world");

使用c++編寫可靠的多執行緒的**,認真考慮下面的建議:

參考目標平台的文件,了解改平台的同步原語,比如原子操作、記憶體屏障

最好將平台的原語用自己設計的抽象包裝起來:比如使用pthread;

確保正在使用的型別在多執行緒程式中使用是安全的: 保證非共享的物件獨立; 確定在不同執行緒中使用該型別的同乙個物件到底是不是需要加鎖、考慮最合適的加鎖粒度;

如果編寫可能用於多執行緒的型別,必須完成兩項任務:

確保不同執行緒可以不加鎖地使用該型別的不同物件;

必須明確且提供不同執行緒使用該型別的同乙個物件需要做的操作: 是否需要考慮外部加鎖: 呼叫者自己負責加鎖 是否需要內部加鎖:為每個公有成員函式的操作加鎖。比如生產者-消費者模型通常使用內部加鎖。需要考慮:第一、 確認該型別的物件總是要被跨執行緒共享;第

二、型別介面的設計應該有利於粗粒度、自給自足的操作。如果內部的鎖加得很合適,那麼對呼叫者而言是透明無感的。第

三、不變物件(唯讀的、常量字串)不需加鎖。

確保資源為物件所擁有,使用顯式的raii和智慧型指標

使用raii時,小心複製建構函式和賦值建構函式;

使用智慧型指標而非原始指標來儲存動態分配的資源:shared_ptr

應該顯式地執行資源分配(比如new);

馬上將申請分配的資源賦予給管理物件:

比如:void fun(shared_ptr sp1, shared_ptr sp2);fun(shared_ptr(new widget), shared_ptr(new widget));

由於引數初始化的順序可能因為編譯器的不同而改變,一種極端的情況是:同時執行了對兩個物件的new 操作的記憶體分配操作,然後再試圖呼叫兩個widget 建構函式。如果這個時候某個構造函式呼叫丟擲異常,另外乙個物件的記憶體就永遠沒有機會釋放了。

解決方法:絕對不要在一條語句中分配乙個以上的資源,應該顯式地執行資源分配(比如new),然後馬上將申請分配的資源賦予給管理物件。例如:

shared_ptr sp1(new widget);shared_ptr sp2(new widget);

fun(sp1, sp2);

C 高階之三 型別安全和STL 儲存之廚

不要動態地處理陣列 這裡主要有兩個意思 不用支援動態地基類的指標進行 n這種操作,因為它實際會按基類大小進行偏移計算,而非預期地按照子類的大小進行偏移計算 2.盡量在介面中使用引用而非指標,原因就在於期望清楚地表面所討論的是乙個物件,而不是物件陣列 不要使用失效物件 經常容易忽略的失效物件包括 語義...

2023年C 專家高階之一

2012年c 專家高階之一 序號 比較項 malloc new 說明 1應用範圍 cc 僅僅是c 語言 new是c 語言新引進的操作符,c 相容c語言,或者說對c語言進行擴充 2操作符 不是new以及delete是3過載 在c 語言可以 過載是物件導向語言的特性 4建構函式 malloc僅僅申請記憶...

《浪潮之巔》筆記之一

浪潮之巔 吳軍 我在google總部曾接待了很多中國 的領導幹部,他們都關心為什麼美國小公司能很快成為跨國公司,我認為其中乙個原因是反壟斷法逼著公司進行科技進步。當乙個公司開始壟斷乙個行業時,它會更多地傾向於利用自己的壟斷資源,而不是科技進步獲得更多的利潤,畢竟前者比後者容易得多。董事會裡除了大投資...