Trích dẫn lựa chọn từ cppreference:
Tính đa hình thời gian chạy này cho phép các đối tượng sử dụng polymorphic_allocator hoạt động như thể chúng sử dụng các loại bộ cấp phát khác nhau tại thời điểm chạy mặc dù cùng loại bộ cấp phát tĩnh
Vấn đề với trình phân bổ "thông thường" là họ thay đổi loại vùng chứa. Nếu bạn muốn vector
có một trình phân bổ cụ thể, bạn có thể sử dụng Allocator
tham số mẫu:
auto my_vector = std::vector<int,my_allocator>();
Vấn đề bây giờ là vectơ này không cùng loại với vectơ có bộ cấp phát khác. Ví dụ: bạn không thể chuyển nó vào một hàm yêu cầu vectơ cấp phát mặc định hoặc gán hai vectơ có kiểu cấp phát khác nhau cho cùng một biến / con trỏ, ví dụ:
auto my_vector = std::vector<int,my_allocator>();
auto my_vector2 = std::vector<int,other_allocator>();
auto vec = my_vector; // ok
vec = my_vector2; // error
Bộ cấp phát đa hình là một loại bộ cấp phát đơn với một thành viên có thể xác định hành vi của bộ cấp phát thông qua điều phối động thay vì thông qua cơ chế mẫu. Điều này cho phép bạn có các vùng chứa sử dụng phân bổ cụ thể, tùy chỉnh, nhưng vẫn thuộc loại phổ biến.
Việc tùy chỉnh hành vi của trình cấp phát được thực hiện bằng cách cung cấp cho trình cấp phát một std::memory_resource *
:
// define allocation behaviour via a custom "memory_resource"
class my_memory_resource : public std::pmr::memory_resource { ... };
my_memory_resource mem_res;
auto my_vector = std::pmr::vector<int>(0, &mem_res);
// define a second memory resource
class other_memory_resource : public std::pmr::memory_resource { ... };
other_memory_resource mem_res_other;
auto my_other_vector = std::pmr::vector<int>(0, &mes_res_other);
auto vec = my_vector; // type is std::pmr::vector<int>
vec = my_other_vector; // this is ok -
// my_vector and my_other_vector have same type
Vấn đề chính còn lại, như tôi thấy, là một vùng std::pmr::
chứa vẫn không tương thích với vùng std::
chứa tương đương bằng cách sử dụng trình cấp phát mặc định. Bạn cần phải đưa ra một số quyết định tại thời điểm thiết kế giao diện hoạt động với vùng chứa:
- có khả năng vùng chứa được chuyển vào có thể yêu cầu phân bổ tùy chỉnh không?
- nếu vậy, tôi có nên thêm một tham số mẫu (để cho phép các trình cấp phát tùy ý) hay tôi nên bắt buộc sử dụng một trình cấp phát đa hình?
Giải pháp khuôn mẫu cho phép bất kỳ trình cấp phát nào , bao gồm cả trình cấp phát đa hình, nhưng có những nhược điểm khác (kích thước mã được tạo, thời gian biên dịch, mã phải được hiển thị trong tệp tiêu đề, tiềm ẩn nguy cơ "nhiễm loại" tiếp tục đẩy vấn đề ra bên ngoài). Mặt khác, giải pháp cấp phát đa hình ra lệnh rằng phải sử dụng trình cấp phát đa hình . Điều này loại trừ việc sử dụng std::
các vùng chứa sử dụng trình cấp phát mặc định và có thể có ý nghĩa đối với việc giao tiếp với mã kế thừa.
So với trình cấp phát thông thường, trình cấp phát đa hình có một số chi phí nhỏ, chẳng hạn như chi phí lưu trữ của con trỏ memory_resource (rất có thể là không đáng kể) và chi phí điều phối hàm ảo để cấp phát. Vấn đề chính, thực sự, có lẽ là thiếu khả năng tương thích với mã kế thừa không sử dụng bộ cấp phát đa hình.
allocator<T>
vốn có. Vì vậy, bạn sẽ thấy giá trị trong đó nếu bạn sử dụng trình phân bổ thường xuyên.