Để hiểu enum
, hãy bắt đầu với việc xem xét hàm hủy mà không có nó:
~scoped_ptr() {
delete ptr_;
}
ở đâu ptr_
a C*
. Nếu loại C
là không đầy đủ vào thời điểm này, tức là tất cả những gì trình biên dịch biết là struct C;
, sau đó (1) một mặc định tạo làm-gì destructor được sử dụng cho các trường hợp C chỉ vào. Đó không phải là điều đúng đắn để làm đối với một đối tượng được quản lý bởi một con trỏ thông minh.
Nếu việc xóa thông qua con trỏ đến kiểu không hoàn chỉnh luôn có Hành vi không xác định, thì tiêu chuẩn có thể chỉ yêu cầu trình biên dịch chẩn đoán và không thành công. Nhưng nó được xác định rõ ràng khi trình hủy thực sự là tầm thường: kiến thức mà lập trình viên có thể có, nhưng trình biên dịch không có. Tại sao ngôn ngữ định nghĩa và cho phép điều này là ngoài tôi, nhưng C ++ hỗ trợ nhiều phương pháp mà ngày nay không được coi là phương pháp tốt nhất.
Một kiểu hoàn chỉnh có kích thước đã biết và do đó, sizeof(C)
sẽ biên dịch nếu và chỉ khi C
là một kiểu hoàn chỉnh - với hàm hủy đã biết. Vì vậy, nó có thể được sử dụng như một người bảo vệ. Một cách sẽ đơn giản là
(void) sizeof(C);
Tôi đoán rằng với một số trình biên dịch và các tùy chọn, trình biên dịch sẽ tối ưu hóa nó trước khi nó có thể nhận thấy rằng nó không nên biên dịch và đó enum
là một cách để tránh hành vi trình biên dịch không phù hợp như vậy:
enum { type_must_be_complete = sizeof(C) };
Một lời giải thích thay thế cho sự lựa chọn enum
thay vì chỉ là một biểu thức bị loại bỏ, chỉ đơn giản là sở thích cá nhân.
Hoặc như James T. Hugget đề xuất trong một nhận xét cho câu trả lời này, "enum có thể là một cách tạo ra một thông báo lỗi giả di động tại thời điểm biên dịch".
(1) Bộ hủy không làm gì được tạo mặc định cho kiểu không hoàn chỉnh là một vấn đề với cũ std::auto_ptr
. Nó xảo quyệt đến mức nó được đưa vào mục GOTW về thành ngữ PIMPL , được viết bởi chủ tịch hội đồng tiêu chuẩn hóa C ++ quốc tế Herb Sutter. Tất nhiên, ngày nay điều đó std::auto_ptr
không còn được dùng nữa, thay vào đó người ta sẽ sử dụng một số cơ chế khác.
ptr_
chính nó ởsizeof
dạngsizeof(*ptr_)
thay vìsizeof(C)
.