在面向對象的開發過程中,經常出現類的繼承,這裡面出現的成員函數的重載(overload)、覆蓋(override)與隱藏(hidden)很容易混淆。
首先澄清這3個概念:
重載
覆蓋(派生類函數覆蓋基類函數)
隱藏(派生類的函數屏蔽了與其同名的基類函數)
下面用一個簡單的例子來闡述
#include <iostream> using namespace std; class Base { public: virtual void vf(float x) { cout << "Base::vf(float) " << x << endl; } void g(float x) { cout << "Base::g(float) " << x << endl; } void h(float x) {cout << "Base::h(float) " << x << endl; } }; class Derived : public Base { public: virtual void vf(float x) { cout << "Derived::vf(float) " << x << endl; } void g(int x) { cout << "Derived::g(int) " << x << endl; } void h(float x) { cout << "Derived::h(float) " << x << endl; } }; // http://www.cnblogs.com/roucheng/ int main() { Derived d; Base *pb = &d; Derived *pd = &d; // Good : behavior depends solely on type of the object pb->vf(3.14); // Derived::vf(float) 3.14 pd->vf(3.14); // Derived::vf(float) 3.14 // Bad : behavior depends on type of the pointer pb->g(3.14); // Base::g(float) 3.14 pd->g(3.14); // Derived::g(int) 3 (suprise!) // Bad : behavior depends on type of the pointer pb->h(3.14); // Base::h(float) 3.14 (suprise!) pd->h(3.14); // Derived::h(float) 3.14 return 0; }
例子中,pb和pd指向同一地址,按理運行結果是相同的,但其實卻不是。由於隱藏機制的作用,部分方法的調用依賴於所使用的指針!
由此看來,隱藏機制似乎會帶來不少理解上的問題,但“存在即合理”:
總結
工欲善其事,必先利其器。弄清楚這些基本概念,才能在實踐中少走彎路。
http://www.cnblogs.com/roucheng/p/3470287.html