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

时间:2011-09-05 03:44:15

标签: c++ templates swap

对我来说似乎是C ++模板的月......

我有一个SecureString。 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)现已消失。对于后代来说,已经为这个主题中的函数提供了参考。

杰夫

1 个答案:

答案 0 :(得分:9)

不幸的是......不。

这不是rebind的用途。使用rebind是因为分配器用于在STL中分配一种类型的对象和一种类型(std::allocator<T>)。

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

但是,在您的情况下,您的分配器和rebind分配器是不同的,因此它们不能交换内存。所以你来做副本。

您可以优化std::string操作,但不能优化此操作。

一个问题:为什么不void swap(SecureString&, SecureString&)