gpt4 book ai didi

用于扩展任意标准符合分配器的 C++ 设计模式

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:58:22 24 4
gpt4 key购买 nike

我目前正在寻找扩展任意标准符合分配器类型的最佳方法。要清楚:我不想编写自定义分配器。我只想将一个特定的扩展或行为“添加”到一个已经存在的扩展或行为中。我已经创建了一个示例,它看起来像什么。请注意,以下代码仅用于说明目的。

#ifndef HPP_SMART_ALLOCATOR_INCLUDED
#define HPP_SMART_ALLOCATOR_INCLUDED


#include <memory>
#include <map>


template<typename T>
struct allocator_traits;

template<typename T, class allocator_type = std::allocator<T>>
class smart_allocator;


template<>
struct allocator_traits<void>
{
typedef std::allocator<void>::const_pointer const_pointer;
typedef std::allocator<void>::pointer pointer;
typedef std::allocator<void>::value_type value_type;
};

template<typename T>
struct allocator_traits
{
typedef typename std::allocator<T>::const_pointer const_pointer;
typedef typename std::allocator<T>::const_reference const_reference;
typedef typename std::allocator<T>::difference_type difference_type;
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::reference reference;
typedef typename std::allocator<T>::size_type size_type;
typedef typename std::allocator<T>::value_type value_type;
};


template<class allocator_type>
class smart_allocator<void, allocator_type>
: public allocator_traits<void>
{
public:
template<typename U> struct rebind { typedef smart_allocator<U, typename allocator_type::rebind<U>::other> other; };
};

template<typename T, class allocator_type>
class smart_allocator
: public allocator_traits<T>,
private allocator_type
{
public:
using typename allocator_traits<T>::const_pointer;
using typename allocator_traits<T>::const_reference;
using typename allocator_traits<T>::difference_type;
using typename allocator_traits<T>::pointer;
using typename allocator_traits<T>::reference;
using typename allocator_traits<T>::size_type;
using typename allocator_traits<T>::value_type;
template<typename U> struct rebind { typedef smart_allocator<U, typename allocator_type::rebind<U>::other> other; };

smart_allocator() throw() /*noexcept*/;
smart_allocator(allocator_type const&) throw() /*noexcept*/;
virtual ~smart_allocator() throw();

virtual ~smart_allocator()
{
std::map<pointer, size_type>::iterator i = this->m_map.begin();
while (i != this->m_map.end())
{
this->allocator_type::deallocate(i->first, i->second);
++i;
}
}

pointer allocate(size_type n, allocator_traits<void>::const_pointer hint = 0)
{
pointer p = this->allocator_type::allocate(n, hint);
this->m_map.insert(std::pair<pointer, size_type>(p, n));
return p;
}

void deallocate(pointer p, size_type n) /*noexcept*/
{
std::map<pointer, size_type>::iterator iter = this->m_map.find(p);
if (iter != this->m_map.end())
this->allocator_type::deallocate(iter->first, iter->second);
}

using allocator_type::address;
using allocator_type::construct;
using allocator_type::destroy;
using allocator_type::max_size;

private:
smart_allocator(smart_allocator const&) throw();
smart_allocator& operator=(smart_allocator const&);

std::map<pointer, size_type> m_map;
};


#endif /* HPP_SMART_ALLOCATOR_INCLUDED */

请考虑以下注意事项:

  • 模板参数 allocator_type 可以是任何标准符合类型。它不限于 std::allocator。这是所有 STL 实现都使用的相同技术。
  • 从 allocator_type 派生时,我们需要使用私有(private)继承,因为 std::allocator 成员函数中没有一个是虚函数。但是,std::allocator& alloc = smart_allocator() 不会做您可能期望的事情。

你认为这适用吗?

最佳答案

您当然需要实现一个复制构造函数和复制赋值运算符,否则当容器按值传递分配器时您的映射可能会被破坏(具体来说,您可能会导致双重删除)。可能还有其他我没有注意到的注意事项。

关于用于扩展任意标准符合分配器的 C++ 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6334556/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com