- static_cast
比較不安全。例如把子類別指標轉成父類別指標,這是可以的。但是把父類別指標轉成子類別指標,會很危險。
*dynamic_cast
有回傳值,透過檢查回傳值的方式來提高安全性。
比較不安全。例如把子類別指標轉成父類別指標,這是可以的。但是把父類別指標轉成子類別指標,會很危險。
*dynamic_cast
有回傳值,透過檢查回傳值的方式來提高安全性。
什麼是 "轉送" 呢? 假設現在要到某家公司去取文件,跟櫃台小姐說明來意後,他會告訴你應該到 "業務窗口" 去處理。當你走到業務窗口後,那邊又告訴你這份文件目前由 "客戶服務部" 負責;因此你得再到客戶服務部去一趟,找到客戶服務部後,小姐還是很客氣的說文件應該要到 "文管中心" 去拿。像這樣子把自己的要求傳送下去,一直找到適當的人選或地點就是 "轉送"。
例如,現在產生一個要求,但無法直接決定處理該要求的物件。這時候,可以把一個以上的物件串聯成鎖鏈狀,依序走過這個連鎖物件再決定最後目的地的物件。 如果使用這個 Pattern,可以降低 "要求端" 和 "處理端" 之間的結合性,讓它們個別成為獨立的零件。另外,還可支援有需依發生狀況改變處理要求的物件的程式。 先對人產生一個要求,如果這個人有處理的能力就處理掉;如果不能處理的話,就把要求轉送給 "第二個人"。同樣的,如果第二個人有處理能力的話就處理掉,不能處理的話,就繼續轉送給第三個人,以此類推。
這個程式會產生問題以及決定解決問題的人 ...
class與struct有很明顯的的差別是,class可以定義member function,但struct不行。另外,class預設的member權限是private,而struct預設則是public。
以下是我看螞蟻書的重點整理。另外,也有參考這篇。
以下講權限範圍,如果沒有定義的話,則預設表示private。其實跟java很類似,差別在於java沒有friend class,而且java的預設權限是package scope。
建構子跟解構子也很重要,以前不太清楚解構子可以幹嘛,只知道物件被回收的時候解構子會自動被呼叫。 以下這個例子我覺得很好 ...
當類別在執行作業時,會呼叫自己類別或其他類別的方法,呼叫方法之後的結果會反應在物件狀態上,但卻不會留下任何作業紀錄。
遇到這種情形的時候,要是有一個類別能表現"請執行這項作業"的"命令"時就方便多了。因為如此一來便可以用一個"表示命令的類別物件個體"來代表要執行的作業,而不需要採用"呼叫方法"之類的動態處理。如想管理相關紀錄時,只需要管理該物件個體的集合即可。而若預先將命令的集合儲存起來,還可以再執行同一個命令;或者是把多個命令結合成一個新命令供再利用。
這樣的Pattern叫作Command Pattern,有時也稱為"Event",跟"Event driven"中的Event是同一個意思。一旦發生事件(例如按下滑鼠左鍵,或按下右鍵),則先將該事件變成物件個體,按照發生順序排入queue中。接著,再依序處理所有排列等候的事件。
設計一個簡單的繪圖軟體,移動滑鼠的時候,便會自動產生一個個紅點,按下clear即可清除。 當使用者移動滑鼠的時候,就會產生"在這裡畫一個點"的command。把這個物件個體儲存起來,需要用的時候就可以繼續畫紅點。
常見有三種定義方式。
struct Edge
{
int from, to, weight;
bool operator<(Edge other) const
{
return weight > other.weight;
}
};
void printOut(Edge e){
printf("%d\n",e.weight);
}
vector<Edge> v;
sort(v.begin(), v.end());
v.push_back((Edge){1,1,1});
v.push_back((Edge){1,2,5});
v.push_back ...
舉例來說,目錄和檔案都可以放在目錄底下,因此可以一視同仁。
可以把目錄想成是容器,檔案想成是內容,容器底下可能是內容,也可能是更小一號的容器。
以模擬方式表示檔案和目錄的程式。表示檔案的類別是 File 類別、表示目錄的是 Directory 類別,兩者合併起來就是父類別 Entry 類別。Entry 類別是表示目錄進入點的類別,對 File 和 Directory 一視同仁的類別。
表示內容的參與者。不可以放入其他東西。例如 File 類別。
表示容器的參與者。可放入 Leaf 或 Composite。例如 Directory 類別。
對 Leaf 和 Component ...
海綿蛋糕、鮮奶油蛋糕、草莓奶油蛋糕或生日蛋糕的原型其實都是海綿蛋糕,只不過運用了各種修飾技巧,能符合不同目的而改變。
物件也很像是蛋糕的多變化,首先建立一個像是海綿蛋糕的核心物件,再一層層加上裝飾用的功能,就可以完全符合所需的物件。
在字串周圍加上裝飾外框後再列印出來的程式。裝飾外框是指以-,+,| 等字元組成的框線。
新增功能的核心參與者。在蛋糕的比喻說明中,相當於裝飾前的海綿蛋糕。Component 只規定海綿蛋糕的介面。例如 Display 類別。
實作 Component 介面的具體海綿蛋糕。例如 StringDisplay 類別。
具有跟 Component 參與者相同的介面,另外還有 Decorator 要修飾的 Component。這個參與者是 "早就知道" 自己要去修飾的對象。例如 Border 類別。
程式這個東西往往愈做愈大,許多類別彼此間的影響讓關係更加錯綜複雜。因此在使用類別時,要確實了解類別之間的關係,正確依序呼叫方法。 利用大型程式進行資料處理時,必須精確控制相關的類別。既然如此,就乾脆設個處理專用的"窗口",如此一來就不需要個別控制類別,只要把要求丟給"窗口"即可。
Facade Pattern 能整合錯綜複雜的來龍去脈,提供較為高級的介面。Facade 參與者則是讓系統外埠看到較簡單的介面。而且 Facade 參與者還會兼顧系統內部各類別功能和互動關係,以最正確的順序利用類別。
設計一個產生使用者 Web 網頁的程式。 以三個類別的簡單系統為例,這個系統中包含有利用郵件信箱取得姓名的資料庫(Database)、產生 HTML 檔的類別(HtmlWriter)以及提供較高級介面的類別(PageMaker,也就是 Facade 參與者)。
構築成系統的其他參與者之"單一窗口"。Facade 對系統外部提供較高級且單一的介面。例如 ...
關於macro的介紹,有一個還不錯的網站。
在debug的時候很常用printf來debug,並且會註明這是哪一個變數名稱,用macro可以很容易作到。
#define print_var(var) printf("%s: %s\n", #var, var)
//也可以這樣
#define PRINT_TOKEN(token) printf(#token " is %d", token)
char s[] = "aaa";
//s: aaa
print_var(s);
int a = 5;
//a is 5
PRINT_TOKEN(a);
如果想要一次印出多個變數,可以這樣做。
#define print_var(var) do { printf("%s: %s\n", #var ...
一個指向struct的指標用動態配置之後,在記憶體裡面是長甚麼樣子?
struct myFtphdr {
short mf_opcode;
unsigned short mf_cksum;
union {
unsigned short mf_block;
char mf_filename[1];
}__attribute__ ((__packed__)) mf_u;
char mf_data[1];
}__attribute__ ((__packed__));//告訴編譯器不做最佳化
printf("%d",sizeof(myFtphdr)) //The size of myFtphdr = 6 bytes
//現在配置一個512+6 = 518的記憶體空間給指向myFtphdr的指標
//但是myFtphdr不是只有六個byte,那剩下的512個byte到哪裡去了?
struct myFtphdr *packet = (struct myFtphdr*) malloc(512+6);
//分配512個byte給mf_data,但是mf_data只有一個byte ...