1. Vấn đề nó giải quyết
API C thường trả quyền sở hữu qua T**, không khớp trực tiếp smart pointer C++. std::out_ptr và std::inout_ptr thích nghi output parameter rồi khôi phục quyền sở hữu RAII sau đó.
2. Kiến thức cần có
Ngày 3: chuyển quyền sở hữu.
Ngày 6: RAII và lifetime tài nguyên.
3. Ý tưởng cốt lõi
Adapter tạm mở một cửa raw pointer có kiểm soát. out_ptr chờ output mới; inout_ptr còn đưa pointer hiện có cho hàm C thay thế. Hãy xác định giá trị đang được biến đổi rồi kiểm tra kiểu, lifetime hoặc quyền sở hữu kết quả. Bật C++23 chưa chắc thư viện đã triển khai đủ, vì vậy cần kiểm tra feature-test macro liên quan.
4. Cú pháp tối thiểu
legacy_create(std::out_ptr(owner));5. Cách nó hoạt động
Ví dụ tạo biểu thức hoặc đối tượng nhỏ nhất cho
std::out_ptrvàstd::inout_ptr.Chương trình cho các hàm create và replace kiểu C nhỏ điền
std::unique_ptrkhi được hỗ trợ.Cuối cùng, nó in hoặc kiểm tra giá trị do smart pointer sở hữu sau khi thích nghi để dễ đối chiếu.
6. Lỗi thường gặp
Dùng
inout_ptrvới API không giải phóng cũng không thay pointer cũ có thể rò rỉ hoặc double-delete; custom deleter phải khớp hàm cấp phát C.Không kiểm tra feature-test macro có thể chọn nhánh mã thư viện hiện tại chưa hỗ trợ.
7. Khi nào nên dùng
Nên dùng khi kết nối smart pointer sở hữu với output parameter C cũ có hợp đồng rõ.
Tránh dùng khi API C++ mới, vốn nên trả trực tiếp RAII owner thay vì lộ
T**.
8. Ví dụ đơn giản
Trình nạp ảnh cũ ghi handle mới cấp phát qua Handle**, còn C++ lưu kết quả trong unique owner. Chương trình dùng dữ liệu cố định để output dễ kiểm tra.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp23/32_out_ptr_inout_ptr/main.cpp
#include <iostream>
#include <memory>
#include <version>
#if defined(__cpp_lib_out_ptr)
void create_value(int** output) {
*output = new int(7);
}
void replace_value(int** output) {
delete *output;
*output = new int(9);
}
#endif
int main() {
#if defined(__cpp_lib_out_ptr)
std::unique_ptr<int> owner;
create_value(std::out_ptr(owner));
replace_value(std::inout_ptr(owner));
std::cout << *owner << '\n';
#else
std::cout << "out_ptr and inout_ptr unavailable\n";
#endif
}
9. Điều cần nhớ
Tách quy tắc chuẩn khỏi mức hỗ trợ thực tế.
Làm rõ lifetime, ownership và kiểu suy luận.
Ưu tiên cú pháp ngắn, đúng ý định.
Guard tính năng chưa được hỗ trợ đồng đều.
10. Câu hỏi tự kiểm tra
Dễ — Cú pháp ngắn nhất ở Phần 4 là gì và nhiệm vụ chính của nó là gì?
Trung bình — Đọc chương trình mẫu: giá trị, kiểu hoặc nhánh nào được quan sát, và vì sao?
Khó — Vì sao
out_ptrphù hợp với owner rỗng còninout_ptrcần hợp đồng chính xác về cách hàm C xử lý pointer cũ?