Boost::Any
使用通用基类placehoder
从中派生模板holder
类。 placehoder
提供了一个虚拟方法接口,特别是一种检索any包含的typeid的方法。然后,any包含指向placeholder
的指针。我不明白的是placeholder
的目的和虚拟方法的使用。让any
的简化结构(接口的源可用here):
class any
{
public:
template<typename ValueType>
any(const ValueType & value) : content(new holder<ValueType>>(value)) {}
private:
class placeholder
{
public:
virtual const std::type_info & type_info() const = 0;
};
template<typename ValueType>
class holder : public placeholder
{
public:
holder(const ValueType &value) : held(value) {};
virtual const std::type_info &type_info() const
{
return typeid(ValueType);
}
const value_type held;
};
placeholder *content;
}
我认为placeholder
可以完全删除,placeholder *content;
替换为holder *content;
。
此外,我不理解any
中使用的分配机制。让:
any & operator=(any rhs)
{
any(rhs).swap(*this);
return *this;
}
将any
与另一个签署。这将构建一个临时any
rhs
content
swap
和any
与当前对象,有效地做我们想要的但是......什么变成了如果any
只是系统地构造一个新的临时{{1}}并将其影响到当前对象以进行所有赋值操作,那么这一切是什么意思?
答案 0 :(得分:5)
在我看来,占位符可以完全删除,占位符*内容; 替换为持有人*内容;。
不,因为holder
是模板类,所以这是无效的:
holder * content
你需要写
holder<T> * content
但你不知道T
- (这是boost::any
的全部意义)。
因此,您可以为所有holder<T>
类创建一个公共基类 - 这就是placeholder
。
而且,我不理解任何使用的分配机制。让:
any & operator=(any rhs)
{
any(rhs).swap(*this);
return *this;
}
这是众所周知的“复制和交换”习语。考虑更标准的实现是什么样的:
any & operator=(const any &rhs)
{
//Watch out for self-assignment.
if(&any==this) return *this;
//Clean out the old data
delete content;
// Update our content
content = rhs.content->clone();
return *this;
}
这复制了复制构造函数中的许多行为。复制和交换习惯用法是一种删除重复的方法。复制由复制构造函数完成,清理由临时析构函数完成。
我认为奇怪的是operator=
获取副本作为其参数,因为它不接受const引用,然后从该引用创建第二个副本。我原以为:
any & operator=(const any & rhs)
{
any(rhs).swap(*this);
return *this;
}
或
any & operator=(any rhs)
{
rhs.swap(*this);
return *this;
}