1.2 說了 hello world 後再做什麼(32)
2. 技術(27-30)
2.2 在簇中分配物件(28)
2.3 應用器、操縱器和函式物件(29)
2.4 將應用程式從輸入輸出中分離出來(30)
3. 庫(23-26)
3.3 庫設計就是語言設計
3.4 語言的設計就是庫的設計
4. 碎碎念
因為肺炎的事情,整個假期都一直宅在家裡。在為祖國母親擔心、為武漢加油的同時,發現「宅」屬性被自己挖掘出來,並沒有覺得無聊,相反感受了下風平浪靜的閒暇(ps 向奮戰在一線的偉大醫護人員致敬。
終於把一直在看的《c++沉思錄看》完了,有很多細節的地方還是沒有看懂的,可是讀書不就是這個樣子,不可能一次就會,每次看都會有每次看的體會吧。對於覺得很新奇或者印象很深刻的地方做個筆記,方便下次閱讀。
因為後面的部分是最近看完的,那就從後往前總結吧。
設計任何一門語言——也可以說是任何軟體——都是有特定的背景的。c++ 使用者願意為了語言所以提供的強大的表現力和高效率而放棄對簡單性的要求。
1.1.1 類庫和語言語義
所有程式語言都是幫助人們用計算機來解決問題的工具。由於這些問題越來越複雜,以及越來越多的人想要使用計算機來解決不同的問題,所以就不可避免地有了要將這種複雜性轉交給語言的壓力。
初學 c++ 的人很難理解賦值和初始化的區別:
1.1.2 抽象和介面c++ 的乙個基本思想就是通過類定義可以指明當這個類被物件構造、銷毀、複製、賦值時應該發生什麼事情。
跟蹤類,存在的目的是為了讓世界知道它們的存在,常用該類來跟蹤函式的進入和退出。
2.1.1 設計乙個實用的跟蹤類——跟蹤函式
列印函式入口和出口 =》 支援重定向輸入的列印函式入口和出口 =》支援開關+重定向輸入的列印函式的入口和出口
2.1.2 生成物件的審計跟蹤——跟蹤物件
類真的按照你的想法建立和銷毀了嘛,你以為你以為的就是你以為的……,證據說話,最有效,給段**自己體會下。
class obj_trace
2.2.2 方案 1—— 侵入
對型別本身的侵入性比較重,假設 t 是乙個物件的型別。需要以某種方式放入特定的 cluster c 中。
為了使上面的方案有效,型別 t 需要存在乙個成員 operate new 將 cluster 作為引數。該操作需要改變 cluster,所以 cluster 這個引數必須按照引用傳遞。成員 opreate new 的宣告如下:
void * t::operate new(size_t, cluster &);注意:
2.2.3 方案 2——非侵入
知識源於生活,但是高於生活。c++ 繼承的概念,很像取自於生活,但是變通性更強。此處通過使用繼承和乙個中間層。即可完成將任何類的物件放入到乙個 cluster 中。定義乙個基類 clusteritem,從這個基類派生出來的派生類物件都可以分配到簇中。
class clusteritem
注:詳細的例子見書 p322。
規規矩矩的搬了小板凳又看一次還是沒懂……,先記下來吧,後面也許某天會突然頓悟也說不准呢。
已知:cout << value
可以使變數 value 的值出現在 cout 檔案,則cout << flush
也可以用來強行輸出緩衝區的資料。
書上的定義寫的實在是拗口且難以理解……,沒看錯,他就是這麼寫的,懷疑是翻譯有問題上述的例子中,flush 定義為乙個操縱器, << 操作符定義為乙個應用器。
核心目標:設計乙個類來表示任意 i/o 庫的介面,從而使應用程式與 i/o 之間的耦合大為下降。
動機:庫應該使用哪種 i/o 裝置,把庫**到某個特定的 i/o 裝置會限制庫的靈活。
2.4.1 問題
定義如下的變長字串的類:
class string
支援string fullname = "hello world" cout << fullname << endl;
操作需要在上述類中包含乙個輸出函式:
ostream& opreate<<(ostream& o, const string& s)
弊端:
2.4.1 抽象輸出——有瑕疵的解決方案
class writer
class filewriter: public writer
void send(const char *p, int n)
}private:
file *fp;
}
#includewriter& operator<<(writer& w, const string& s)
return w
}
弊端:
string hello = "hello\n", goodbye = "goodbye\n"
filewriter(stdout) << hello << goodbye; 這種寫法不對。
原因:filewriter(stdout) 是乙個臨時值,在第乙個 << 操作完成後,這個臨時值就可能被銷毀掉……
2.4.2 技巧而無蠻力c++ 是可擴充套件的。使用者不能改變底層語言本身——不能增加新的操作符或者改變語法,但是可以為這門語言增加新的型別。如果某一組累的設計和實現是希望得到廣泛應用,那麼我們就稱之為庫。
問題:將兩份文字加以合併,兩份文字分別是標準庫提案描述,以及標準庫工作組所維護的開放討論列表。
解決:awk perl 和 snobol 這樣的模式匹配語言
用 c++ 編寫程式
由於目的是生成 c++ 的標準文件,作者認為 c++ 才名正言順……,你開心就好
解決過程不詳細說明,結論是問題的快速解決依賴於 c++ 庫的四種功能:
資料抽象的目的就是控制複雜度。如果對某個物件的所有單個操作都將物件置於一種合理的狀態,那麼物件的狀態就會始終保持合理。
3.2.1 複雜問題
先看下面 c 程式存在的問題
#include
#include
main()
3.2.2 優化介面
在 c++ 中重新設計介面,以便在可能的地方不用考慮上述的問題。解法——將上述例子中的, dir 指標,換成 dir 物件,dir 物件表示對目錄的一次從檢視。
注:參考 p278
3.2.3 溫故知新c++ 的類機制賦予了庫設計者非同尋常的力量,效果上相當於把他們轉成了潛在的語言設計者。
先看乙個簡單的字串類
class string
~string()
operator char*()
private:
int sz;
char* data;
}
3.3.1 記憶體耗盡
問:木有足夠的空間包含被分配的 string 會發生什麼問題呢?
答:類定義沒有考慮這種情況,所以我也不知道,皮一下很開心
,正確回答是,建構函式裡的 new 表示式失敗了,在目前的實現中,通常會有三種結果:
注:標準的 c++ 要求實現丟擲異常,但是很多程式的實現會採用「相容模式」返回 0。3.3.2 複製
問:將某個長度的 string 賦給乙個長度不同的 string 應該怎麼做?
答: 讓我們先想下可能性:
以上四種回答肯定都有其適用的情況,無分對錯,場景不同而已。
複製建構函式和賦值操作符之間的主要區別是:賦值操作符複製新值之前必須刪除舊值。3.3.3 隱藏實現
string 類看上去好像是隱藏了其內部實現,但是分析 public 的operator char*()
的實現可以發現:
3.3.4 預設建構函式
原因:如果不知道 string 的初始化值,就無法建立它。即string s
的定義會導致編譯錯誤。
結果:上述問題是沒有預設的建構函式導致的,解決方案是為 string 類增加乙個預設的建構函式。
主要討論的內容是:c++ 中哪些簡化庫設計的部分,設計乙個好的程式庫的要求之一就是徹底隔離介面和實現。使用庫提供的字串類,使用者不必知道字串內部的實現細節。
包括:
注:這章理解的並不是很好,有空重補下?嗯,先就這個樣子吧
雖然還是有很多細節不理解,但是終於寫完了上篇的總結,明天應該會是個好天氣吧,希望確診的人數不要增加,希望每個人都:
JDBC學習筆記 上篇
二 獲取連線connection 三 得到執行sql語句的物件statement 四 執行sql語句,並返回結果 五 處理結果集 查詢得到的resultset 總結記錄一下jdbc的學習筆記,mysql版本5.7,驅動版本5.1.47 1.註冊驅動的方式如下 drivermanager.regist...
《C 沉思錄》 筆記
calss trace trace file ff void print char s void on void off private int noise file f 4.是不是每個建構函式初始化所有的資料成員?5.類需要析構函式嗎?6.類需要乙個虛析構函式嗎?class b b class d...
Vue的學習筆記(上篇)
vue 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,vue 被設計為可以自底向上逐層應用。vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合。另一方面,當與現代化的工具鏈以及各種支援類庫結合使用時,vue 也完全能夠為複雜的單頁應用提供驅動。v model指...