荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: Version (Who makes history and why), 信区: Program
标 题: boost::any实现分析
发信站: 荔园晨风BBS站 (Tue Mar 25 18:49:42 2003), 站内信件
boost::any实现分析
看了boost::any的源码受到启发,写点心得。:)
boost::any并不是一个类模板,而仅是一个普通类。但它的成员函数type()却
可以在运行时返回不同的类型信息(type_info)。这种功能的实现依靠了两种技
术:
(1)成员函数/构造函数模板
(2)继承自普通类的类模板
以下讨论boost::any如何运用这两种技术来实现其功能。
首先,boost::any有一个构造函数模板:
template<typename ValueType>
any(const ValueType & value);
用于在初始时刻由其参数,通过编译器的类型推断来获得value的类型信息。
value必须保存下来提供给any_cast使用,而value的类型信息ValueType也必须以
某种形式保存下来供成员函数type()使用。但是由于boost::any并不是一个类模板
,所以它不能有一个ValueType或者SomeClass<ValueType>这样依赖于ValueType的
成员变量,也就是说,由于boost::any是一个普通类,所以它的成员变量必须有一
个不依赖于ValueType的预先确定的类型。
如果我们使用void*类型来存放value,就会丢掉类型信息。试图使用
type_info型的变量来保存类型信息是行不通的。(看一下type_info的声明就会知
道,它的copy constructor, operator=以及operator&都是私有的。)也就是说,
我们必须使用一个确定类型的成员变量来保存不确定的类型信息。为此,把虚函数
和类模板结合起来。在boost::any中使用的方法就是,用一个虚基类指针
placeholder*作为成员变量的类型,该类拥有一个纯虚函数type():
virtual const std::type_info & type() const = 0;
placeholder必须是一个确定类型的类,但它的派生类却可以是模板类,其中
可以使用ValueType的相关类型来保存value,同时也不丢失其类型信息,而且可通
过虚函数type()来重新获得该类型信息:
template<typename ValueType>
class holder : public placeholder
{
public: // structors
holder(const ValueType & value)
: held(value)
{
}
public: // queries
virtual const std::type_info & type() const
{
return typeid(ValueType);
}
...
public: // representation
ValueType held;
};
同时,在any类的构造函数模板中将new holder<ValueType>(value)赋予它的
成员变量content(类型为placeholder*)。
以后,在any::type()中通过调用虚函数holder<ValueType>::type()来获得该
类型信息:
const std::type_info & type() const
{
return content ? content->type() : typeid(void);
}
在any_cast函数中,则通过boost::type()来保证类型安全。以指针类型的
any_cast为例:
template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType>
*>(operand->content)->held
: 0;
}
附:boost::any的代码(去掉了预处理宏和namespace boost{}修饰):
class any
{
public: // structors
any()
: content(0)
{
}
template<typename ValueType>
any(const ValueType & value)
: content(new holder<ValueType>(value))
{
}
any(const any & other)
: content(other.content ? other.content->clone() : 0)
{
}
~any()
{
delete content;
}
public: // modifiers
any & swap(any & rhs)
{
std::swap(content, rhs.content);
return *this;
}
template<typename ValueType>
any & operator=(const ValueType & rhs)
{
any(rhs).swap(*this);
return *this;
}
any & operator=(const any & rhs)
{
any(rhs).swap(*this);
return *this;
}
public: // queries
bool empty() const
{
return !content;
}
const std::type_info & type() const
{
return content ? content->type() : typeid(void);
}
private: // types
class placeholder
{
public: // structors
virtual ~placeholder()
{
}
public: // queries
virtual const std::type_info & type() const = 0;
virtual placeholder * clone() const = 0;
};
template<typename ValueType>
class holder : public placeholder
{
public: // structors
holder(const ValueType & value)
: held(value)
{
}
public: // queries
virtual const std::type_info & type() const
{
return typeid(ValueType);
}
virtual placeholder * clone() const
{
return new holder(held);
}
public: // representation
ValueType held;
};
private: // representation
template<typename ValueType>
friend ValueType * any_cast(any *);
placeholder * content;
};
/////////////////////////////////////////////////////////////////////
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const throw()
{
return "boost::bad_any_cast: "
"failed conversion using boost::any_cast";
}
};
template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType>
*>(operand->content)->held
: 0;
}
template<typename ValueType>
: 0;
}
template<typename ValueType>
const ValueType * any_cast(const any * operand)
{
return any_cast<ValueType>(const_cast<any *>(operand));
}
template<typename ValueType>
ValueType any_cast(const any & operand)
{
const ValueType * result = any_cast<ValueType>(&operand);
if(!result)
throw bad_any_cast();
return *result;
}
--
*
* *
* *
no more to say
★ just wish you ★
good luck
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.1.50]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店