2012-05-11 25 views
10

Ở đây theo "đơn giản", tôi có nghĩa là một lớp học với không phá hủy rỗng ảo hoặc loại POD.Chúng ta có cần gọi rõ ràng hàm hủy cho "các lớp POD đơn giản" được phân bổ với "vị trí mới" không?

điển hình ví dụ:

char buffer[SIZE]; 
T *p = new(buffer) T; 
... 
p->~T(); // <---- always ? 

gì sẽ xảy ra nếu chúng ta không gọi destructor rõ ràng về p? Tôi không nghĩ rằng đó là hành vi không xác định hoặc rò rỉ bộ nhớ.
Có vấn đề gì với việc sử dụng lại buffer không?

+0

@EdChum Tại sao? Anh ta đặt một vật thể lên trên bộ đệm đó. – Benj

+0

@Benj xin lỗi chỉ nhận ra sai lầm của tôi – EdChum

+1

Với vị trí mới, bạn có chịu trách nhiệm gọi điện cho destructor của bất kỳ loại phụ nào không? – Benj

Trả lời

9

Đối với loại POD hoặc một lớp có số tầm thường destructor: no. Tuổi thọ của đối tượng sẽ kết thúc khi bộ nhớ cho đối tượng được giải phóng hoặc sử dụng lại. Bạn không cần phải gọi destructor một cách rõ ràng nếu bạn không muốn.

Điều đó nói rằng, không có lý do gì để không. Đối với một kiểu với một destructor tầm thường thì cuộc gọi destructor sẽ không tạo ra mã nào. Nếu có, bởi một lớp có một destructor "rỗng", bạn cho phép khả năng lớp có các thành viên hoặc các lớp cơ sở với các destructors không tầm thường thì bạn có thể nhận được hành vi không xác định nếu chương trình của bạn dựa vào các destructors được gọi.

Lưu ý rằng người dùng cung cấp destructor là một destruct không tầm thường ngay cả khi nó không phải là ảo và trống. Mặc dù vậy, bạn vẫn được phép kết thúc vòng đời của một đối tượng với một destructor như vậy bằng cách giải phóng hoặc sử dụng lại bộ nhớ của nó miễn là chương trình của bạn không phụ thuộc vào bất kỳ tác dụng phụ nào của destructor. (Xem 3.8 [basic.life]/4 của ISO/IEC 14882: 2011)

+0

"_bạn có thể nhận được hành vi không xác định nếu chương trình của bạn dựa vào các destructors được gọi là._" tuyên bố này không có ý nghĩa. Bạn nhận được hành vi được xác định, hành vi của mã của bạn. – curiousguy

+1

@curiousguy: Nếu mã có một hành vi được xác định thì theo định nghĩa, nó không thể dựa vào các destructor như vậy được gọi. Tôi không chắc chắn rằng phần này của tiêu chuẩn nói rất nhiều khác ngoài vòng cung cấp cho một gợi ý ở định nghĩa "dựa vào" nhưng tôi không nghĩ rằng nó không phù hợp. –

+0

"_ Tôi không nghĩ rằng nó không phù hợp" Không. Nó chỉ là tautological. Bạn cũng có thể nói rằng mã mà hy vọng 'cout <<" ";' để in 'Xin chào, Thế giới' là không xác định ... std có rất nhiều báo cáo vô lý, và đây là một trong những yêu thích của tôi. – curiousguy

12

Về mặt kỹ thuật, giả định rằng trình hủy không giải phóng bất kỳ tài nguyên nào có được trong quá trình xây dựng, có thể không cần thiết.

Tuy nhiên, xem xét các khía cạnh phi kỹ thuật - bảo trì và phát triển mã - Tôi sẽ tuân theo thực tiễn tốt nhất - những gì được xây dựng, nên bị hủy. Kịch bản cần xem xét - điều gì sẽ xảy ra nếu trong tương lai một số thay đổi sẽ xác định mã có liên quan được đưa vào trình phá hủy? Bạn sẽ nhớ rằng bạn đã làm hỏng sự phá hủy của loại đối tượng đó?

+2

Tôi sẽ có ý nghĩa phổ biến hơn một trích dẫn tiêu chuẩn ngớ ngẩn bất cứ ngày nào! – Pubby

+1

Tôi thích phần 'Tôi sẽ tập trung vào phần thực hành tốt nhất'. –

1

Nếu lớp của bạn xử lý một số tài nguyên (bộ nhớ heap, xử lý, bộ đếm, mutexes ...) hoặc chứa một số trường xử lý tài nguyên, tài nguyên này sẽ không được giải phóng nếu bạn không gọi hàm hủy một cách rõ ràng. Nếu không, không có bất kỳ rắc rối nào với sự hủy diệt. Bạn có thể xem xét lớp không bị hủy như một rác trong bộ nhớ và xây dựng một cái mới một cách tự do ở cùng một chỗ.

+0

Anh ấy đang nói về các loại POD ... tại sao anh ta lại giữ một mutex, counter…. – celavek

+0

POD có thể chứa con trỏ hoặc xử lý để mutex có thể được mua trong khi xây dựng/suốt đời của đối tượng – inkooboo

+3

@inkooboo: POD có thể chứa con trỏ nhưng chỉ có thể chứa tay cầm nếu loại xử lý cũng là POD. Các mutex không thể có được trong quá trình xây dựng một đối tượng POD vì điều đó có nghĩa là POD có một nhà xây dựng không tầm thường. –

0

Có, bạn phải gọi hàm hủy một cách rõ ràng (hãy ghi nhớ các tác dụng phụ của T, tức là giải phóng bộ nhớ bổ sung). Ngoài ra, bạn phải cẩn thận về sự liên kết bộ nhớ khi sử dụng vị trí mới.

Nếu muốn, bạn có thể sử dụng lại bộ nhớ đệm.

Vui lòng tham khảo http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14

+0

Không thực sự là câu hỏi, OP hỏi về POD – Benj

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