Alokátory
Standardní knihovna C++ používá alokátory ke zpracování přidělování a navracení prvků uložených v kontejnerech. Všechny kontejnery standardní knihovny C++ s výjimkou std::array mají parametr šablony typu , kde představuje allocator<Type>Type typ elementu kontejneru. Třída vector je například deklarována takto:
template <
class Type,
class Allocator = allocator<Type>
>
class vector
Standardní knihovna C++ poskytuje výchozí implementaci alokátoru. V C++11 a novějších verzích se výchozí alokátor aktualizuje tak, aby zpřístupňuje menší rozhraní. Nový alokátor se nazývá minimální alokátor. Konkrétně minimální člen alokátoru podporuje sémantiku přesunutí, což může construct() výrazně zlepšit výkon. Ve většině případů by měl být tento výchozí alokátor dostačující. V jazyce C++11 podporují všechny typy a funkce standardní knihovny, které převezměte parametr typu alokátoru, minimální rozhraní alokátoru, včetně std::functionshared_ptr, allocate_shared() , a basic_string . Další informace o výchozím alokátoru najdete v tématu třída alokátoru.
Psaní vlastního alokátoru (C++11)
Výchozí alokátor používá new a k přidělení a přidělení delete paměti. Pokud chcete použít jinou metodu přidělení paměti, například pomocí sdílené paměti, musíte vytvořit vlastní alokátor. Pokud cílíte na C++11 a potřebujete napsat nový vlastní alokátor, vytvořte z něj minimální alokátor, pokud je to možné. I v případě, že jste už implementovali alokátor starého stylu, zvažte jeho úpravu tak, aby byl minimálním alokátorem, abyste mohli využít efektivnější metodu, která vám bude automaticky k dispozici.
Minimální alokátor vyžaduje mnohem méně často používaný a umožňuje zaměřit se na členské funkce a , které allocatedeallocate dělají všechnu práci. Při vytváření minimálního alokátoru neimplementujte žádné členy kromě členů uvedených v následujícím příkladu:
převádějící kopírovací konstruktor (viz příklad)
operator==
operator!=
allocate
Navrátit
Výchozí člen C++11, který vám bude k dispozici, zajišťuje dokonalé předávání a umožňuje sémantiku přesunu. Je mnohem efektivnější v mnoha případech než construct() starší verze.
Upozornění
V době kompilace používá standardní knihovna C++ třídu allocator_traits ke zjištění explicitně zadaných členů a poskytuje výchozí implementaci pro všechny členy, které nejsou k dispozici. Nezasahujte do tohoto mechanismu tím, že pro alokátor allocator_traits specializaci prostředků.
Následující příklad ukazuje minimální implementaci alokátoru, který používá a mallocfree . Všimněte si použití nového typu výjimky, který je vyvolán, pokud je velikost pole menší než nula nebo větší než std::bad_array_new_length maximální povolená velikost.
#pragma once
#include <stdlib.h> //size_t, malloc, free
#include <new> // bad_alloc, bad_array_new_length
#include <memory>
template <class T>
struct Mallocator
{
typedef T value_type;
Mallocator() noexcept {} //default ctor not required by C++ Standard Library
// A converting copy constructor:
template<class U> Mallocator(const Mallocator<U>&) noexcept {}
template<class U> bool operator==(const Mallocator<U>&) const noexcept
{
return true;
}
template<class U> bool operator!=(const Mallocator<U>&) const noexcept
{
return false;
}
T* allocate(const size_t n) const;
void deallocate(T* const p, size_t) const noexcept;
};
template <class T>
T* Mallocator<T>::allocate(const size_t n) const
{
if (n == 0)
{
return nullptr;
}
if (n > static_cast<size_t>(-1) / sizeof(T))
{
throw std::bad_array_new_length();
}
void* const pv = malloc(n * sizeof(T));
if (!pv) { throw std::bad_alloc(); }
return static_cast<T*>(pv);
}
template<class T>
void Mallocator<T>::deallocate(T * const p, size_t) const noexcept
{
free(p);
}
Psaní vlastního alokátoru (C++03)
V jazyce C++03 musí všechny alokátory používané s kontejnery standardní knihovny C++ implementovat následující definice typů:
const_pointer
const_reference
difference_type
pointer
rebind
reference
size_type
value_type
Kromě toho musí jakýkoli alokátor používaný s kontejnery standardní knihovny C++ implementovat následující metody:
Konstruktor
Kopírovací konstruktor
Destruktor
address
allocate
construct
deallocate
destroy
max_size
operator!=
operator==
Další informace o těchto definicích typů a metodách najdete v tématu třída alokátoru.