原文:當“友元”遇到“虛函數” http://student.csdn.net/space.php?uid=112600&do=blog&id=17266
要理解有時候,人們其實就是在故意做這種事,最典型的做法,就是通過非虛函數調用虛函數:
- class B
- {
- public:
- void Action()
- {
- this->DoAction();
- }
- private:
- virtual void DoAction() = 0; //一個私有的純虛函數
- // friend class A;
- };
任何一個合格的C++程序員,都應該學會這種作法。DoAction是一個純虛函數,這裏我們更決絕一點,乾脆讓它是私有的,這就是逼着派生類自己去實現一個完全自我的DoAction(),假設有個class D : public B,並且聽話地實現了DoAction。具體D的定義,爲節省點篇幅,不寫了。
注意到第11行的註釋, class A 現在已經不是 B 的友員了,但不要緊,我們只是想在新版的類A中,調用Action函數,而它是public的,所以這裏不需要友元來攪和。
- class A
- {
- void test()
- {
- B* pb = new D; //pb 實際指向一個D對象。
- pb->Action(); // Action 是 公開的,所以可以調用
- }
- };
pb 調用了非虛的B::Action函數,但在Action內調用了虛函數DoAction,再由於pb實際指向的是D對象,所以最終調用的是D::DoAction()——這了無新意對不對?只要學過一點C++的多態,都會懂這一點。沒錯,它太司空見慣了,基本上所有C++程序員每天都會在寫類似的代碼——這就是我想說的,有時候,看起來在調用基類的代碼,但實際上在調用派生類的代碼。假設我們修改了語法規則,逼着虛函數在遇上友元之後失效,那就是逼着程序員不去用friend,去將更多本來應該是private的成員,用各種該法寫成public的。