這段code的規格是
初始化玩遊戲後,確保有一個使用者在遊戲裡面,所以要在init結束前呼叫join。
至於規格為什麼要這樣設計,不要問我XD
原本的code是python的。我把python的code轉成用c++來表達,所以function前面都會有virtual,以符合python情形。
#include <cstdio> class Father{ public: virtual int init(){ printf("father init start\n"); printf("father init end\n"); return join(); } virtual int join(){ printf("father join start\n"); printf("father join end\n"); } }; int main(){ Father father; father.init(); }
坦白講,這段程式碼看起來還好。除了一個function做兩件事情外。也沒什麼。執行順序也如我們的預期
可是如果他是基底類別。會有子類別繼承他father init start father init end father join start father join end
#include <cstdio> class Father{ public: virtual int init(){ printf("father init start\n"); printf("father init end\n"); return join(); } virtual int join(){ printf("father join start\n"); printf("father join end\n"); } }; class Child:public Father{ public: virtual int init(){ printf("child init start\n"); int ret = Father::init(); // do something It need. printf("child init end\n"); return ret; } virtual int join(){ printf("child join start\n"); Father::join(); printf("child join end\n"); } }; int main(){ Child child; child.init(); }
程式碼看起來還好,只是執行解果有點詭異。恩....子類別join發生在子類別init完成前。
child init start father init start father init end child join start father join start father join end child join end child init end
假設你不care這情形,過了一段時間,你突然想新增一些東西像這樣
#include <cstdio> class Father{ public: virtual int init(){ printf("father init start\n"); printf("father init end\n"); return join(); } virtual int join(){ printf("father join start\n"); printf("father join end\n"); } }; class Child:public Father{ public: int special; virtual int init(){ printf("child init start\n"); int ret = Father::init(); special = 1; // do something It need. printf("child init end\n"); return ret; } virtual int join(){ printf("child join start\n"); Father::join(); printf("special = %d\n", special); printf("child join end\n"); } }; int main(){ Child child; child.init(); }
你在子類別新增一個變數,初始化時需要給他一個值,子類別的join的時候會需要他。你會發現這樣寫,special的值不合你預期(廢話,因為join發生在special = 1之前)。
怎麼辦,把special = 1移到Father::init前面就好了。 恩....
問題好像解決了,也沒什麼呀
有一天,父類別要做一些更動,要多加一個屬性name,父類別的name是從1開始算,子類別的name是從2開始算。
像這樣
#include <cstdio> class Father{ public: int name; virtual int init(){ printf("father init start\n"); name = 1; printf("father init end\n"); return join(); } virtual int join(){ printf("father join start\n"); printf("name = %d\n", name); printf("father join end\n"); } }; class Child:public Father{ public: int special; virtual int init(){ printf("child init start\n"); name = 2; special = 1; int ret = Father::init(); // do something It need. printf("child init end\n"); return ret; } virtual int join(){ printf("child join start\n"); name += 1; Father::join(); printf("special = %d\n", special); printf("child join end\n"); } }; int main(){ Child child; child.init(); }
在join那邊初始化?
不行,join在那邊會被呼叫很多次,所以在join初始化會一直讓那個變數被初始化
所以不能在那初始化。
所以怎麼辦?
不要呼叫父類別的函數好了,把父類別的函數程式碼直接複製到子類別好了
很好,問題解決了,只是這樣幹嘛用繼承呢?
如果你哪天父類別的init改了,恭喜你。你要把父類別的code重新複製到子類別去。
每改一次,複製一次 ...
不小心改錯,你的code就gg了。
有人會說,我就是要初始化完呼叫,那該怎麼辦呢?
事實上也不難。
#include <cstdio> class Father{ public: int name; virtual int init(){ printf("father init start\n"); name = 1; printf("father init end\n"); } virtual int join(){ printf("father join start\n"); printf("name = %d\n", name); printf("father join end\n"); } int init_and_join(){ //the functino can't be overrided. init(); return join(); } }; class Child:public Father{ public: int special; virtual int init(){ printf("child init start\n"); int ret = Father::init(); name = 2; special = 1; // do something It need. printf("child init end\n"); return ret; } virtual int join(){ printf("child join start\n"); name += 1; Father::join(); printf("special = %d\n", special); printf("child join end\n"); } }; int main(){ Child child; child.init_and_join(); }
這樣問題就解決了,我們只要呼叫init_and_join()就可以了。他會幫我們完成初始化和join的動作。如果你在寫java,你還可以再init_and_join()前面加個final,防止子類別override,導致行為改變。
Sometimes sex toys can even have sex toy store medical makes use of if you have a sexual dysfunction or medical condition. There are many different types of|several varieties of|various sorts of} sex toys, different people|and folks} use them tons of|for lots of|for many} completely different reasons. We actually have a dildo with a suction cup for unmatched pleasure wherever may be}. Compared to other sex toys in the marketplace, utilizing a dildo might be preferable. Unlike some sex toys, asilicone dildo has a firm but flexible design.
回覆刪除