c++:使用自定义分配器时高效的swap()

C++: efficient swap() when using a custom allocator

本文关键字:高效 swap 分配器 自定义 c++      更新时间:2023-10-16

这似乎是我的c++模板之月…

我有一个安全字符串。SecureString看起来就像std::string,只不过它使用了一个自定义分配器,在销毁时归零:

class SecureString
{
public:
  typedef std::basic_string< char, std::char_traits<char>, zallocator<char> > SecureStringBase;
  typedef zallocator<char>::size_type size_type;
  static const size_type npos = static_cast<size_type>(-1);
  ....
private:
  SecureStringBase m_base;
};

SecureString的完整代码可以在http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/SecureString.h;分配器的代码可以在http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h上找到。

目前,我们定义了一个swap,它接受std::string作为实参:

void SecureString::swap(std::string& str)
{
  SecureStringBase temp(str.data(), str.size());
  m_base.swap(temp);
  str = std::string(temp.data(), temp.size());
}

我觉得我在swap中错过了一个机会,因为底层类型只因分配器而不同。有人能想到避免临时的方法吗?是否有可能使用rebind使此运行更快?

编辑:SecureString::swap(std::string& str)现在不见了。本文中对函数的引用已保留,以供后人参考。

杰夫

不幸的是…没有。

这不是rebind的作用。之所以使用rebind,是因为分配器在STL中只分配一种类型的对象(std::allocator<T>)。

然而,有一个技巧。例如,当您实例化std::list<T, std::allocator<T>>时,allocator不必分配T s,它必须分配一些内部结构,而不是像__list_node<T>一样,这就是当rebind被使用时,它创建了一个新的分配器,先例的兄弟(它们只是模板参数不同,并且可能共享相同的内存池)。

但是在您的例子中,您的分配器和std::string分配器是不同的,因此它们不能交换内存。所以你做一个拷贝。

您可以优化void swap(SecureString&, SecureString&)操作,但不能优化这个操作。

一个问题:为什么不是typedef std::string<char, SecureAllocator<char>> SecureString; ?