大忙人系列-程序猿在想什么 (四·一) C++的食用方法

B站的日更終于榨干了腦子,之后就隨便想起啥寫啥吧。
一. 多態(tài)+狀態(tài)機(怎么又是你)
一如既往的狀態(tài)機。
第一次對這個東西好像似懂非懂的時候還是在想著怎么整游戲邏輯,當(dāng)時用的是python,作為個duck type,python自然沒什么活好整,不過后來想了想C艸怎么整。
具體邏輯是這樣,一個游戲當(dāng)然除了標(biāo)題界面外還有游戲界面、戰(zhàn)斗界面、菜單界面。不同界面有相同行為當(dāng)然是整個多態(tài)的活,都從一個類里面繼承而來然后重載個像update呀render或者draw呀,然后沒對象new一個出來就行。但是,戰(zhàn)斗結(jié)束或者從菜單退出以后要回到上一個界面,所以需要額外的一個棧來保存歷史的數(shù)據(jù);按具體的按鍵能進入其他界面,就需要狀態(tài)機+按鍵的結(jié)構(gòu),比如從標(biāo)題界面按回車進入地圖界面,再按Esc進入菜單界面,全部都是狀態(tài)的轉(zhuǎn)換。
另一個例子是在動畫中,比如unity的動畫系統(tǒng)就有個狀態(tài)機。再比如《游戲編程模式》里面的例子,從輸入的模塊獲得了輸入以后如何影響玩家控制的角色,傳統(tǒng)的方式連個簡單的趴下和跳躍都會有很多情況(趴下中跳躍、跳躍中空中趴下),如果全部在輸入模塊里面處理肯定是地獄,這個時候?qū)存I數(shù)據(jù)派發(fā)給主角類然后主角類根據(jù)自身的狀態(tài)自己改變自己,從而能既完善又好編碼。
二. 局部性
主要是看《游戲編程模式》看到這個就順便水點東西吧。局部性這東西,雖然平時寫代碼沒必要特別考慮,但是也見過作死結(jié)果還把自己埋了的。局部性就時間局部性和空間局部性,盡量讓要操作的數(shù)據(jù)挨的近一點總沒啥錯。而且OOP經(jīng)常被黑犧牲性能加強邏輯,所以也整除了面向數(shù)據(jù)編程(也就是說可以不用再面朝著對象【滑稽】)。
遙想當(dāng)年讓寫一個冒泡排序排十萬個短字符串吧,一直挪字符串肯定很蠢,就簡單的用指針+std::vector<std::string>然后補個compare函數(shù)就行(排序和字符串比較默認(rèn)順序好像不一樣的,有改動所以要自己寫),指針雖然破壞局部性但是這個例子下其實還好啦,最后用gcc跑了二十幾秒吧。然后某日常被我黑的同學(xué)就跑來找我說他的程序已經(jīng)跑了幾個小時了還沒出結(jié)果,一看,Debug下,還沒有用std::string,自己整個局部的字符數(shù)組又用指針又拷字符串,看的我一臉懵逼。
三. 模板
模板一時爽,一直模板一直爽,只是報錯看不懂。
簡單的模板可以很簡單,就是可以批量生成應(yīng)對不同類型但是核心算法相同的代碼而只用寫一次,比如一個鏈表,無論存啥數(shù)據(jù)結(jié)構(gòu)基本的算法與操作都一樣,那就沒必要不同鏈表都實現(xiàn)一次。
e.g.
template<typename T>
class LinkedList {
public:
???? LinkedList();
???? ~LinkedList();
???? void insert(const LinkedList* pos,const T& data);
???? ......
private:
????LinkedList* head;
};
如此一來,一個簡單的鏈表就成型了(雖然實戰(zhàn)這么寫會被人打死)。
除此之外,還可以用函數(shù)模板。上面在類前是類模板,那在函數(shù)前就是函數(shù)模板了。
如果以上的都能看懂,恭喜您知道了有個東西叫模板了,接下來當(dāng)然是type_traits SFINAE metaprogramming云云的各種騷得C艸之父Bjarne自己都沒想到可以這么整活的操作了。
想當(dāng)年某編譯課被安排了搞traits的活,還以為是去整點type_traits里面的黑科技,最后發(fā)現(xiàn)居然是老師叫我們?nèi)ゲ椴?,對,就那個宇宙第一PHP,為了支持“多重繼承”整活整出來的辣雞語法。就本質(zhì)而言,雖然在語法層級上的技術(shù)不同,但都是給已有的類擴功能,C艸、Python、Ruby有各種騷操作而已(PHP你真雞兒丟人趕緊退群吧你這不就個interface人家Java的interface都升級了)。
雖然隨著某C艸的版本更新,不少私活已經(jīng)可以通過新語法解決了,但是去看老一輩整的活,還是會驚嘆這些人都怎么想到的怎么可以這么整。
<= to be continued(好像第一大部分的幾次忘記加了?)