第一招虛函數
通過衍生類別來進行功能擴充是基本的物件導向的方式,這種方式大如下:
class base
{
public:
virtual ~base(){}
virtual void fun()
{
cout << "準系統" << endl;
}
};
class derive:public base
{
public:
void fun()
{
cout << "擴充功能" << endl;
}
};
這種方式下,基類通過聲明虛函數,讓衍生類別來覆蓋,最後通過多態來實現擴充功能。這種方式的最大的缺點是基類的編寫者一般很難確定虛函數的功能究竟要實現到什麼程度,如果有一天突然發現一個虛函數的功能要進行擴張(或收縮),那麼所有從這個基類派生的類都要進行編譯。這種方式的另一個缺憾是。功能的擴充不能在運行時設定。
第二招組合
通過組合方式來為類的功能擴充留下餘地的方式,要比通過繼承的方式在耦合方面要松的多。就是把上面的虛函數所要委託給一個其它的類。這種方式大體如下:
class action
{
public:
virtual void fun()
{
cout << "準系統" << endl;
}
};
class exAction:public action
{
public:
virtual void fun()
{
cout << "擴充功能" << endl;
}
};
class app
{
public:
app():paction(NULL){}
virtual ~app(){}
virtual void fun()
{
if(paction)
paction->fun();
}
void setActoin( action* action_)
{
paction = action_;
}
private:
action* paction;
};
在這個例子中,類app把它的功能委託給了類action。這樣一來,類app就和它的功能進行瞭解藕。解藕後的類app現在可以在運行時進行功能設定了。通過組合的方式雖然解藕了也能進行功能的運行時設定了。但卻明顯地不如第一種方式效率高。
第三招函數指標成員
通過函數指標成員方式,可以提高效率。這種方式大體如下:
class app
{
public:
app():pfun(NULL){}
virtual ~app(){}
typedef void(*FUN)();
void setFun(FUN fun_)
{
pfun = fun_;
}
virtual void fun()
{
if( pfun)
pfun();
}
private:
FUN pfun;
};
第四招成員模板函數
通過為類預留一個成員模板函數,而為類的使用者留下擴充的餘地。這種方式簡捷、幹練。遺憾的是這種方式不能用在動態方面上。這種方式大體如下:
class app
{
public:
app(){}
virtual ~app(){}
template <class T>
void fun( T& t_)
{
cout << "準系統" << endl;
}
};
template < >
void app::fun(int & t_)
{
cout << "擴充功能" << endl;
}
這種方式還能依偏特化的形式進行,具體請參考我的另一篇blog《讓後門能夠偏特化》。使用這種方式最奇妙的是聲明一個模板建構函式來擴充類的構造功能。
第五招模板基類
上面的幾種方式都是針對一個要進行開發的類為這個要開發的類留下擴充餘地。那麼能不能讓要開發的類用來擴充任意的已開發好的類的功能呢?這就是第五招模板基類。這種方式大體如下:
template < class T>
class exApp:public T
{
public:
void fun()
{
cout << "擴充功能" << endl;
}
};
現在我們可以方便的把類exApp的功能添加到任意的其它的類上了。這種擴充方式的功能非常強悍,它甚至引出一個專門的編程方式:“基於策略的編程”。
詳見《C++程式設計就思維》。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/guanwl/archive/2008/05/01/2358073.aspx