C ++ 11 Allocator

I have not seen many good examples or guidelines for creating a custom allocator in C ++ 11. I can see that it has changed from C ++ 03. However, I did not know how to do this.

I have the following that I gathered together as much information as I could find:

// Project Includes
#include "IMemoryManager.h"

// Standard Includes
#include <cstddef>
#include <iostream>
#include <memory>

//------------------------------------------------------------------------------
/// <summary>
/// A STL compliant custom allocator
///
/// Based on Dr Dobbs article
/// http://www.drdobbs.com/the-standard-librarian-what-are-allocato/184403759
/// I attempted to make it C++11 compliant.
/// Takes an Interface to a Memory Manager which will implement the custom memory management solution.
/// </summary>
template <class T>
class CustomAllocator
{
    std::unique_ptr<IMemoryManager> m_memoryManager;

public:

    typedef T value_type;

    /// Allocator takes ownership of memory manager
    CustomAllocator(std::unique_ptr<IMemoryManager> memoryManager)
        :
        m_memoryManager(std::move(memoryManager))
    {
    }

    ~CustomAllocator()
    {
    }

    CustomAllocator(const CustomAllocator & rhs) = delete;
    void operator =(const CustomAllocator & rhs) = delete;

    bool operator == (const CustomAllocator<T> & rhs)
    {
        return true;
    }

    bool operator != (const CustomAllocator<T> & rhs)
    {
        return false;
    }

    template <class U>
    CustomAllocator(const CustomAllocator<U> & rhs)
        :
        m_memoryManager(std::move(rhs.m_memoryManager))
    {
    }

    T * allocate(size_t n)
    {
        const size_t numBytes = n * sizeof(T);
        void * p = m_memoryManager->allocate(numBytes);

        if (!p)
        {
            throw std::bad_alloc();
        }

        std::cout << "Allocated " << numBytes << " bytes for a " << typeid(T).name() << std::endl;
        return static_cast<T *>(p);
    }

    void deallocate(T * p, size_t numObjects)
    {
        const size_t numBytes = sizeof(*p);

        m_memoryManager->free(p);
        std::cout << "Deallocated " << numBytes << " bytes for a " << typeid(T).name() << std::endl;
    }

    void construct(T * p, const T & x)
    {
        // 'Placement new' constructs an object at a specified location
        // The custom allocator seperates allocation from construction
        new(p) T(x);
    }

    void destroy(T * p)
    {
        p->~T();
    }
};

I have a few questions about this.

  • How do I make the operator == and operator! = Not, that it has a member variable that is a unique pointer? Am I just comparing the address of the memory manager? Why does the standard ask me to implement comparison operators in any case, unless it is assumed that this is one of them and it is not copied? Or that?

  • U? , STL , . ?

  • http://en.cppreference.com/w/cpp/concept/Allocator#Allocator_completeness_requirements ?

  • Constocator Allocator, STL?

void RunCustomAllocator()
{
    // Does not compile
    std::vector<ComplexNumber, CustomAllocator<ComplexNumber> > myVector;
    ComplexNumber number(1, 1);
    myVector.push_back(number);
}

? ?

+4

Source: https://habr.com/ru/post/1662020/


All Articles