此人實現的any功能雖然說是足夠,但是代碼可讀性不太好。其實我在想,真有必要實現那麼多功能麽?還搞出個policy模式。。。
基於幾個思想:
any只是一個容器,裡面存放的變量類型應該有完整的獨立管理內存的能力
變量類型的operator =是完善的比如class A{}; A b;A a=b(幾乎所有類型默認都是完善的,有的自定義類重新定義=的話也最後是完善的,若你沒有自定義自己=,導致你內存的洩漏,那是你自己那個類設計上的責任,不應屬於any的考慮范疇)
char*這種傳統的字符串類型按照字符指針來實現(本身用這個的就是自己找事,C++該把它去掉了),stl::string可以正常工作 www.2cto.com
不提供運行時類型檢查功能(用戶需要自己確保any的類型是正確的,1是因為比如iar的編譯器不支持RTTI,舊編譯器也不支持C++11的類型推導,再就是C++編程整體是靜態類型編程思路為主的,實現了反而打亂思路,如果你自己忘記了自己用的是什麼類型那是你的事,也不應該是any的責任。如果你的編譯器支持RTTI或C++11,可以自己輕松加上去動態類型檢查函數,因為代碼極其精簡易懂)
namespace boostStandalone{
namespace anyimpl{
class policyBase{}; //一個空基類,用於作為指針,可以指向眾多實例化後的子類(沒這個的話只能用void*,我討厭它)
template<typename T>
class policy:public policyBase{ //這裡的思想是靜態多態(不是利用virtual而是利用template),產生一系列針對不同類型的policy
public:
T& get_value(){return mValue;}
void assign(const T& _object){mValue=_object;}
private:
T mValue;
};
}
class any{
public:
any():policyPtr(NULL){} //空構造函數
any(any& x){x.releasePolicy();} //拷貝構造函數。這裡的拷貝構造用的思想是所有權轉移,原any被銷毀(資源被轉移)。(因為我覺得會用到拷貝構造的一般在函數調用,這時,原any的資源應該被收回。這樣有個缺點是,拷貝構造函數不能用const修飾)
template<typename T>
any& operator=(const T& x){ //賦值構造
if(policyPtr){
delete policyPtr;
}
policyPtr=new anyimpl::policy<T>;
(static_cast<anyimpl::policy<T>*>(policyPtr))->assign(x);
return *this;
}
template<typename T>
T cast(){ //不像那個哥們那樣拋出異常,因為前面說了,這個函數會忠實的按你給的類型來執行。只有你給對了,他才出的對(就比如,你硬要用uint8的類型去表示uint32,誰也沒辦法。)
return static_cast<anyimpl::policy<T>*>(policyPtr)->get_value();
}
bool ifEmpty(){
return policyPtr==NULL;
}
~any(){
if(policyPtr){
delete policyPtr;
}
}
private:
void releasePolicy(){policyPtr=NULL;} //釋放資源,這樣在析構any的時候就不會把policy資源給釋放掉了,用於資源所有權轉移,即拷貝構造
anyimpl::policyBase* policyPtr;
};
};
以上就是我的實現。我覺得吧。像boost庫實現的,確實真是強悍,事事追求完美,什麼功能都要有,什麼可能性都要顧及,什麼錯誤檢查都要做。搞到用那麼多代碼,編譯時間長不說,怎麼看啊。。。參考網站那個哥們的代碼已經比較不好看了(懂policy的話會容易一些),回頭想想,真有那個必要那麼做嗎?
我針對這個問題給出的實現在上文。我自己就用了這個了。這個實現雖然函數少,但大部分any用的地方都能用,