Alokator
Alokator digunakan oleh Pustaka Standar C++ untuk menangani alokasi dan alokasi elemen yang disimpan dalam kontainer. Semua kontainer Pustaka Standar C++ kecuali std::array
memiliki parameter templat jenis allocator<Type>
, di mana Type
mewakili jenis elemen kontainer. Misalnya, vector
kelas dinyatakan sebagai berikut:
template <
class Type,
class Allocator = allocator<Type>
>
class vector
Pustaka Standar C++ menyediakan implementasi default untuk alokator. Di C++11 dan yang lebih baru, alokator default diperbarui untuk mengekspos antarmuka yang lebih kecil; alokator baru disebut alokator minimal. Secara khusus, anggota alokator construct()
minimal mendukung semantik pemindahan, yang dapat sangat meningkatkan performa. Dalam kebanyakan kasus, alokator default ini harus cukup. Di C++11 semua jenis dan fungsi Pustaka Standar yang mengambil parameter jenis alokator mendukung antarmuka alokator minimal, termasuk std::function
, shared_ptr, allocate_shared()
, dan basic_string
. Untuk informasi selengkapnya tentang alokator default, lihat allocator
Kelas.
Menulis Alokator Anda Sendiri (C++11)
Alokator default menggunakan new
dan delete
untuk mengalokasikan dan membatalkan alokasi memori. Jika Anda ingin menggunakan metode alokasi memori yang berbeda, seperti menggunakan memori bersama, maka Anda harus membuat alokator Anda sendiri. Jika Anda menargetkan C++11 dan Anda perlu menulis alokator kustom baru, jadikan alokator minimal jika memungkinkan. Bahkan jika Anda telah menerapkan alokator gaya lama, pertimbangkan untuk memodifikasinya menjadi alokator minimal untuk memanfaatkan metode yang lebih efisien construct()
yang akan disediakan untuk Anda secara otomatis.
Alokator minimal membutuhkan boilerplate yang jauh lebih sedikit dan memungkinkan Anda untuk fokus pada allocate
fungsi anggota dan deallocate
, yang melakukan semua pekerjaan. Saat membuat alokator minimal, jangan terapkan anggota apa pun kecuali yang ditunjukkan dalam contoh di bawah ini:
konstruktor salinan konversi (lihat contoh)
operator==
operator!=
allocate
deallocate
Anggota default construct()
C++11 yang akan disediakan untuk Anda melakukan penerusan yang sempurna dan memungkinkan pemindahan semantik; jauh lebih efisien dalam banyak kasus daripada versi yang lebih lama.
Peringatan
Pada waktu kompilasi, Pustaka Standar C++ menggunakan allocator_traits
kelas untuk mendeteksi anggota mana yang telah Anda berikan secara eksplisit dan menyediakan implementasi default untuk setiap anggota yang tidak ada. Jangan mengganggu mekanisme ini dengan memberikan spesialisasi allocator_traits
untuk alokator Anda!
Contoh berikut menunjukkan implementasi minimal alokator yang menggunakan malloc
dan free
. Perhatikan penggunaan jenis std::bad_array_new_length
pengecualian baru yang dilemparkan jika ukuran array kurang dari nol atau lebih besar dari ukuran maksimum yang diizinkan.
#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);
}
Menulis Alokator Anda Sendiri (C++03)
Di C++03, alokator apa pun yang digunakan dengan kontainer Pustaka Standar C++ harus menerapkan definisi jenis berikut:
const_pointer
const_reference
difference_type
pointer
rebind
reference
size_type
value_type
Selain itu, setiap alokator yang digunakan dengan kontainer Pustaka Standar C++ harus menerapkan metode berikut:
Konstruktor
Salin konstruktor
Destruktor
address
allocate
construct
deallocate
destroy
max_size
operator!=
operator==
Untuk informasi selengkapnya tentang definisi dan metode jenis ini, lihat allocator
Kelas.