Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;扩展任意符合标准的分配器的设计模式_C++_Design Patterns_Stl_Allocator - Fatal编程技术网

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

C++ C++;扩展任意符合标准的分配器的设计模式,c++,design-patterns,stl,allocator,C++,Design Patterns,Stl,Allocator,我目前正在寻找扩展任意符合标准的分配器类型的最佳方法。明确地说:我不想编写自定义分配器。我只想在已经存在的扩展或行为上“添加”一个特定的扩展或行为。我已经创建了一个这样的示例。请注意,以下代码仅用于说明 #ifndef HPP_SMART_ALLOCATOR_INCLUDED #define HPP_SMART_ALLOCATOR_INCLUDED #include <memory> #include <map> template<typename T>

我目前正在寻找扩展任意符合标准的分配器类型的最佳方法。明确地说:我不想编写自定义分配器。我只想在已经存在的扩展或行为上“添加”一个特定的扩展或行为。我已经创建了一个这样的示例。请注意,以下代码仅用于说明

#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 */
#如果包含NDEF水电站智能分配器#
#定义包含的HPP\u智能\u分配器
#包括
#包括
模板
结构分配器;
模板
类智能分配器;
模板
结构分配器
{
typedef std::分配器::常量指针常量指针;
typedef std::分配器::指针;
类型定义标准::分配器::值类型值类型;
};
模板
结构分配器
{
typedef typename std::分配器::常量指针常量指针;
typedef typename std::分配器::常量引用常量引用;
typedef typename std::分配器::差异类型差异类型;
typedef typename std::分配器::指针指针;
typedef typename std::分配器::引用;
typedef typename std::分配器::大小\类型大小\类型;
typedef typename std::分配器::值\类型值\类型;
};
模板
类智能分配器
:公共分配器
{
公众:
模板结构重新绑定{typedef smart_allocator other;};
};
模板
类智能分配器
:公共分配器,
专用分配器类型
{
公众:
使用typename分配器\u traits::const\u指针;
使用typename分配器_traits::const_引用;
使用typename分配器_traits::difference_type;
使用typename分配器_traits::pointer;
使用typename分配器_traits::reference;
使用typename分配器\u traits::size\u type;
使用typename分配器\u traits::value\u type;
模板结构重新绑定{typedef smart_allocator other;};
smart_分配器()throw()/*noexcept*/;
智能分配器(分配器类型常量&)throw()/*noexcept*/;
虚拟~smart_分配器()抛出();
虚拟~smart_分配器()
{
std::map::iterator i=this->m_map.begin();
而(i!=this->m_map.end())
{
此->分配器类型::解除分配(i->first,i->second);
++一,;
}
}
指针分配(大小\u类型n,分配器\u特征::常量\u指针提示=0)
{
指针p=this->allocator\u type::allocate(n,提示);
this->m_map.insert(std::pair(p,n));
返回p;
}
无效解除分配(指针p,大小\类型n)/*无异常*/
{
std::map::iterator iter=this->m_map.find(p);
如果(iter!=this->m_map.end())
此->分配器类型::解除分配(iter->first,iter->second);
}
使用分配器类型::地址;
使用分配器类型::构造;
使用分配器_type::destroy;
使用分配器\类型::最大\大小;
私人:
智能分配器(智能分配器常量&)throw();
智能分配器和运算符=(智能分配器常量&);
std::map mu map;
};
#endif/*包括HPP智能分配器*/

请考虑以下注释:

  • 模板参数分配器类型可以是任何标准符合类型。它不限于std::分配器。这与所有STL实现使用的技术相同
  • 当从分配器类型派生时,我们需要使用私有继承,因为std::allocator成员函数中的非私有函数是虚拟的。但是,std::allocator&alloc=smart\u allocator()不会执行您可能期望的操作

您认为这适用吗?

您肯定需要实现一个复制构造函数和复制赋值操作符,否则当容器按值传递分配器时,您的映射可能会被破坏(特别是您可能会导致双重删除)。可能还有其他我没有注意到的因素。

我立刻想到的是;正如参考文献所指出的,“装饰器对于使对象适应新的情况非常有用,而无需重新编写原始对象的代码。”如果我理解你的问题,这听起来就像你在追求什么。

嗯,就像我在最初的帖子中所说的:这只是为了举例说明。这并不意味着你不是绝对正确的。我已经添加了应该实现的ctor声明。当您需要扩展一个非虚拟的特定函数的行为时,这将不起作用。在我的std::allocator示例中就是这样。但是,需要通过传递实现抽象基类的对象的实例来创建此模式,但是标准的符合分配器类需要是默认可构造的。