Boost::any 简化单独版实现
此人实现的any功能虽然说是足够,但是代码可读性不太好。其实我在想,真有必要实现那么多功能麽?还搞出个policy模式。。。
基于几个思想:
any只是一个容器,里面存放的变量类型应该有完整的独立管理内存的能力
变量类型的operator =是完善的比如class A{}; A b;A a=b(几乎所有类型默认都是完善的,有的自定义类重新定义=的话也最后是完善的,若你没有自定义自己=,导致你内存的泄漏,那是你自己那个类设计上的责任,不应属于any的考虑范畴)
char*这种传统的字符串类型按照字符指针来实现(本身用这个的就是自己找事,C++该把它去掉了),stl::string可以正常工作 www.zzzyk.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用的地方都能用,
补充:软件开发 , C++ ,