配置器

C++ 標準程式庫使用配置器來配置和解除配置容器中所儲存的元素。 除了 std::array 所有 C++ 標準程式庫容器都有 類型的 allocator<Type> 樣板參數,其中 Type 代表容器元素的類型。 例如,類別 vector 宣告如下:

template <
    class Type,
    class Allocator = allocator<Type>
>
class vector

C++ 標準程式庫提供配置器的預設實作。 在 C++11 和更新版本中,預設配置器已更新為公開一個較小的介面;新的配置器稱為「最小配置器」。 尤其是,最小配置器的 construct() 成員支援移動語意,可大幅改善效能。 在大部分情況下,此預設配置器應該很足夠。 在 C++11 中,所有接受配置器類型參數的標準程式庫類型和函式都支援最小配置器介面,包括 std::functionshared_ptr, allocate_shared()basic_string。 如需預設配置器的詳細資訊,請參閱 allocator 類別

撰寫您自己的配置器 (C++11)

預設配置器使用 newdelete 來配置和取消配置記憶體。 如果您想要使用不同的記憶體配置方法,例如使用共用記憶體,則必須建立您自己的配置器。 如果您的目標是 C++11,而且需要撰寫新的自訂配置器,請儘可能撰寫成最小配置器。 即使您已實作舊式的配置器,還是請考慮修改為「最小配置器」,以善用自動為您提供的更有效率 construct() 方法。

最小配置器需要較少的重複使用,並可讓您專注于 allocatedeallocate 成員函式,以執行所有工作。 建立最小配置器時,以下範例所示的成員除外,請勿實作任何成員:

  1. 轉換複製建構函式 (請參閱範例)

  2. operator==

  3. operator!=

  4. allocate

  5. deallocate

為您提供的 C++11 預設 construct() 成員可執行完美的轉送並啟用移動語意,在許多情況下比舊版更有效率。

警告

在編譯時期,C++ 標準程式庫會 allocator_traits 使用 類別來偵測您已明確提供哪些成員,並為不存在的任何成員提供預設實作。 請勿藉由為配置器提供 的特製化 allocator_traits 來干擾此機制!

下列範例示範配置器使用 mallocfree 時的最小實作 請注意,我們使用新的例外狀況類型 std::bad_array_new_length,當陣列大小低於零或大於允許的大小上限時會擲回此例外狀況。

#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);
}

撰寫您自己的配置器 (C++03)

在 C++03 中,任何與 C++ 標準程式庫容器搭配使用的配置器都必須實作下列類型定義:

const_pointer
const_reference

difference_type
pointer

rebind
reference

size_type
value_type

此外,任何與 C++ 標準程式庫容器搭配使用的配置器都必須實作下列方法:

建構函式
複製建構函式
解構函式

address
allocate
construct

deallocate
destroy
max_size

operator!=
operator==

如需這些類型定義和方法的詳細資訊,請參閱 allocator 類別

另請參閱

C++ 標準程式庫參考