2009-10-28 78 views
6

Tôi bắt gặp một sử dụng lạ của trình phá hủy trong khi làm việc trên một thư viện hiện có. Các destructor của một stack stl vector được phân bổ đã được gọi một cách rõ ràng, khi trường hợp của nó mà đối tượng đó có thể cần phải được sử dụng một lần nữa. Các đối tượng vectơ này là một phiên bản tùy biến một chút của lớp vectơ stl có phương thức clear chuyên dụng. Trong cơ thể hủy có tồn tại hai cuộc gọi phương thức: clear(), _Tidy().C++ ngăn xếp đối tượng được phân bổ, gọi hàm hủy rõ ràng

Tôi đã cố gắng nghĩ ra một lý do chính đáng tại sao destructor này được gọi thay vì chỉ clear nhưng tôi thua lỗ. Bất cứ ai cũng làm sáng tỏ tại sao điều này có thể là một ý tưởng tốt?

+0

Bạn có thể cung cấp mẫu mã, của vectơ vectơ và cách nó được gọi không? –

+3

_Tidy() làm gì? – Brian

+0

Cho chúng tôi biết cách tạo vectơ. – sbi

Trả lời

1

Đó chắc chắn không phải là một ý tưởng hay. Bất kỳ hoạt động nào trên một đối tượng sau khi destructor bắt đầu chạy sản lượng hành vi không xác định.

+0

Hay đúng hơn, sau khi hủy kết thúc?Tôi cho rằng nó có thể hợp lệ nếu bạn xây dựng một cá thể khác tại cùng một vị trí với vị trí mới trước khi thực hiện bất kỳ điều gì khác với cá thể và trước khi nó nằm ngoài phạm vi. – UncleBens

+0

Và các hoạt động này bao gồm các dtor được tự động gọi vào cuối phạm vi. – sbi

+0

@UncleBens: không, ngay khi destructor bắt đầu, bạn nên xem xét đối tượng của bạn không còn tồn tại ... thử sử dụng các hàm ảo từ trình phá hủy của lớp cơ sở thực sự sử dụng bộ nhớ phân bổ heap của lớp dẫn xuất ... ý tôi là gì :)? –

5

Lớp học này có thể sử dụng một số loại phương pháp placement new không? Đó là lần duy nhất tôi có xu hướng thấy những kẻ phá hoại rõ ràng đang được sử dụng.

+0

Đánh tôi với cú đấm trong khi tôi đang viết. ;) – John

1

Có lẽ bộ mã hóa gốc đã quan tâm đến vị trí trong bộ nhớ mà các đối tượng được phân bổ.

Sau đó, hàm hủy phải được gọi một cách rõ ràng, theo this discussion.

+0

Có lẽ là trường hợp kể từ khi thảo luận về một vectơ phân bổ stack. –

5

Vectơ lớn?

Dự đoán tự nhiên ... khi clear() được gọi là véc tơ thường bị làm trống nhưng bộ nhớ không được giải phóng. Đó là lý do tại sao có mẫu

std::vector<T>().swap(vector_to_clear); 

để làm rỗng véc-tơ để sử dụng lại và xóa bộ nhớ được cấp phát.

Có lẽ tác giả gốc không biết mẫu và cố gắng loại bỏ bộ nhớ được cấp phát theo kiểu thời trang độc ác này. (Tôi nghĩ rằng _Tidy giải phóng bộ nhớ được phân bổ)

+0

Các vectơ khác nhau về kích thước nhưng không có kích thước lớn. Tôi rất muốn biết ý định tác giả ban đầu về vấn đề này, và hy vọng đó chỉ là một thỏa thuận sai lệch về bộ nhớ – Colin

+0

Câu hỏi đầu tiên của tôi là những tình huống như sau: – sbi

9

clear() không được bảo đảm để thực sự giải phóng lưu trữ được phân bổ trong vectơ; _Tidy() trong việc triển khai MSVC sẽ thực sự giải phóng bộ nhớ đó, vì vậy điều này có thể được thực hiện như một tối ưu hóa.

Đó là điều xấu, nhưng bạn có thể làm điều đó một cách hợp pháp (không có hành vi không xác định) miễn là lưu trữ được tái sử dụng bởi một đối tượng cùng loại (bỏ qua vòng loại cv) chiếm toàn bộ dung lượng lưu trữ :

T automatic; 
automatic.T::~T(); 
new (&automatic) T(); 

Mục 3.8.7 của tiêu chuẩn C++ mô tả tình huống sử dụng này và giải thích cách hợp pháp; nó thậm chí còn bao gồm một ví dụ tương tự như ở trên.

Các vấn đề liên quan