Bagikan melalui


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:

  1. konstruktor salinan konversi (lihat contoh)

  2. operator==

  3. operator!=

  4. allocate

  5. 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.

Baca juga

Referensi pustaka standar C++