2011-01-15 23 views
7

Tôi thấy trong một số cuốn sách rằng thứ tự hủy của các thành viên dữ liệu trong lớp nên theo thứ tự ngược lại của trật tự xây dựng của họ. Lý do của quy tắc này là gì? Bất kỳ ví dụ được đánh giá cao.Tại sao thứ tự hủy diệt cho vấn đề thành viên dữ liệu?

+3

Tôi không nghĩ rằng đây là thực tiễn được đề xuất, nhưng một tuyên bố đơn giản về thực tế: http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.2 – mkb

Trả lời

12

Điều này phần lớn là để nhất quán. Khi nhiều đối tượng được tạo theo trình tự, chúng luôn bị hủy theo thứ tự ngược lại. Ví dụ, hãy xem xét ví dụ sau với các biến số tự động:

{ 
    A a; 
    B b(a); 
} // b.~B() is called, then 
    // a.~A() is called 

Ở đây, b sử dụng a. Bằng cách đảm bảo các đối tượng bị phá hủy theo thứ tự ngược lại của công trình xây dựng, C++ giúp quản lý đối tượng suốt đời nhiều hơn dễ dàng hơn.

Trong một lớp, bạn có thể chuyển tham chiếu đến một thành viên dữ liệu khi bạn khởi tạo một thành viên dữ liệu khác. Đảm bảo rằng đối tượng bị phá hủy theo thứ tự ngược lại, bạn sẽ có được những hành vi tương tự như với các biến số tự động:

struct S 
{ 
    A a; 
    B b; 

    S() : a(), b(a) { } 
}; 

Lưu ý rằng nó thường không phải là một ý tưởng tốt để có dữ liệu các thành viên đề cập đến nhau, nhưng đó là cả hai có thể và đôi khi hữu ích .

+1

Có lẽ nói chính xác hơn khi đối tượng B xuất hiện sau đối tượng A, B có thể giữ tham chiếu đến A. Đối nghịch không đúng, do đó, hủy theo thứ tự ngược lại (B, rồi A) có ý nghĩa, trong khi phá hủy đối tượng A có thể dẫn đến lỗi, vì B có thể giữ một tham chiếu đến nó. – EmeryBerger

+0

@EmeryBerger Vâng, nhưng chỉ vì tham chiếu thành viên trực tiếp phải được khởi tạo khi xây dựng. Nhưng một tham chiếu không phải là hình thức duy nhất của 'tham chiếu': các thành viên được tự do giữ con trỏ với nhau, và những người đó có thể được đặt bất cứ lúc nào, do đó được tự do để được ra khỏi trật tự và trở thành không hợp lệ. Bên cạnh đó, các thành viên có thể giữ các tham chiếu 'thực' với nhau theo thứ tự nếu tham chiếu nói là thành viên của một vùng chứa động như 'std :: vector'. Vì vậy, không thực sự có bất kỳ 'có thể' hoặc 'không thể' về điều này, chỉ cần _should_ và _should not_. Suy nghĩ đúng về cuộc đời là điều thiết yếu bất kể hình thức tham khảo –

5

Tôi nghĩ có thể bạn đã hiểu lầm. Không phải là thành viên nên bị hủy theo thứ tự này, nhưng họ là được chỉ định.

Có thể quan trọng trong những trường hợp hiếm hoi để biết thứ tự các mục bị hủy.

Ở bất kỳ mức nào, đó là thứ tự các đối tượng bị phá hủy, bạn không thể làm gì với nó nhưng biết rằng đó là những gì đang xảy ra.

2

Thời gian sống trong C++ được lồng càng nhiều càng tốt. Có thể, mặc dù thường hiếm khi các thành viên dữ liệu phụ thuộc trực tiếp vào nhau (ví dụ: chuyển con trỏ của người khác) hoặc gián tiếp (ví dụ như cả hai đều phụ thuộc vào toàn cục, như viết ra stderr), nhưng ngay cả khi họ không ' t, nó là tốt đẹp để có một thứ tự được chỉ định, và làm tổ phù hợp tốt hơn với cách phần còn lại của ngôn ngữ hoạt động (ví dụ như thời gian sống ở phạm vi chức năng) hơn thứ tự khác sẽ. Tất nhiên, theo quy tắc "as-if" trong tiêu chuẩn, nếu trình biên dịch/thực hiện có thể xác định mã người dùng không thể quan sát việc hủy diệt sắp xếp lại, thì nó có thể làm theo ý thích.

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