현재 임의 표준 준수 배열 유형을 확장하는 최선의 방법을 찾고 있습니다. 명확하게 : 나는 커스텀 할당자를 쓰고 싶지 않다. 나는 단지 기존 확장이나 특정 동작을 "추가"하고 싶습니다. 어떻게 생겼는지 샘플을 만들었습니다. 다음 코드는 단지 설명을위한 것입니다. C++ 임의의 표준을 확장하기위한 디자인 패턴 준수 배열
#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()는 예상 한대로 수행하지 않습니다.
적용 하시겠습니까?
흠, 내가 처음 게시물에 말한 것처럼 : 그것은 단지 일러스트레이션 목적을위한 것입니다. 그렇다고 절대적으로 옳지 않다는 의미는 아닙니다. 구현해야하는 ctor 선언을 추가했습니다. – 0xbadf00d