2012-04-02 24 views
9

This answer dấu ngoặc kép C++ chuẩn 3.8:Tại sao không xóa một đối tượng có một destructor với một tác dụng phụ undefined hành vi trong C + + 11? 11

nếu không có cuộc gọi rõ ràng để các destructor hoặc nếu một delete-biểu thức (5.3.5) không được sử dụng để giải phóng lưu trữ, destructor không được được gọi ngầm và bất kỳ chương trình nào phụ thuộc vào các e ff ects phụ được tạo ra bởi destructor có hành vi chưa được xác định.

Phần về trình hủy không được gọi là rõ ràng. Bây giờ giả sử bỏ qua destructor có một tác dụng phụ mà nên có ảnh hưởng đến hành vi của chương trình.

Tại sao hành vi chương trình không được xác định ngay bây giờ? Tại sao các tác dụng phụ sẽ không bị bỏ qua (vì destructor không được gọi) và chương trình chạy bình thường mà không có tác dụng phụ được áp dụng?

+2

Câu hỏi thú vị. Nhưng tại sao một người nào đó không muốn gọi destructor trên một đối tượng khi nó không còn cần thiết? – ereOn

+1

Nếu destructor trong trường hợp này thực hiện các nhiệm vụ không tầm thường cho ví dụ: Đóng các trình điều khiển tài nguyên hoặc thiết lập trạng thái thành một cái gì đó hợp lệ vv, thì hàm hủy không được gọi là ofcourse sẽ ảnh hưởng đến chương trình và sẽ dẫn đến hành vi không xác định. để bỏ qua các tác dụng phụ. –

+0

@ereOn: Singletons đã được đề cập như là một trường hợp sử dụng (tuy nhiên, điều này không nên được coi là thiết kế tốt mặc dù). –

Trả lời

5

Phần quan trọng là phần đầu của đoạn đó (tôi nhấn mạnh):

Một chương trình có thể kết thúc cuộc đời của bất kỳ đối tượng bằng cách tái sử dụng lưu trữ mà các đối tượng chiếm ...

Nếu bạn chỉ cần sử dụng lại bộ nhớ cho một đối tượng có destructor có không phải là được gọi, thì bạn sẽ nhận được hành vi không xác định. Ví dụ, đối tượng có thể đã bắt đầu một thread, hoặc đăng ký một cuộc gọi lại, hoặc một số hành động khác, nơi một thành phần bên ngoài có thể mong đợi đối tượng vẫn còn tồn tại.

+2

Tôi không đồng ý. Trích dẫn đầy đủ thêm * hoặc bằng cách gọi một cách rõ ràng trình phá hủy cho một đối tượng của một kiểu lớp với một destructor không tầm thường *. Vì vậy, destructor sẽ được gọi trong trường hợp này. –

+0

xin lỗi, trong trường hợp nào? Nó nói ** hoặc **, do đó, báo giá của tôi ở trên dường như đứng trên riêng của mình cũng như của bạn. –

+0

Nhưng đó là vấn đề tôi chỉ vào. Cả báo giá * đều tự đứng *. Tiêu chuẩn đưa ra một giải pháp thay thế, nhưng sự lựa chọn không phải là lựa chọn của chúng tôi. * Đối với một đối tượng của một loại lớp với một destructor không tầm thường * cung cấp cho các tiêu chí để lựa chọn giữa hai chi nhánh của ** hoặc **. Và do đó, bất kỳ đối tượng nào có một destructor không trvial (đó là trường hợp thú vị ở đây) sẽ nhận được destructor của nó được gọi là * trước * lưu trữ của nó được tái sử dụng. –

1

Câu hỏi của bạn không có ý nghĩa.

Tại sao các tác dụng phụ không được bỏ qua (vì trình hủy không được gọi) và chương trình chạy bình thường mà không có tác dụng phụ được áp dụng?

Chúng bị bỏ qua, vì chúng sẽ bị kích hoạt bởi trình phá hủy và nó chưa được gọi.

đọc của tôi:

và bất kỳ chương trình phụ thuộc vào phản ff bên e sản xuất bởi các destructor có hành vi ned fi unde.

thật đơn giản, tôi xem nó dưới ánh sáng của RAII. Ví dụ:

#include "Object.hpp" 

struct Manager: private boost::noncopyable { 
    union Raw { 
    char _[sizeof(Object)]; 
    Object o; 
    }; 
    static Raw raw; 

    Manager() { new (raw.o) Object(); } 
    ~Manager() { raw.o.~Object(); } 
}; 

Bây giờ, nếu tôi phân bổ một Manager, quên để tiêu diệt nó, và phân bổ một hình mới, tôi đang ở một nhúm vì tôi ghi đè lưu trữ những người đầu tiên tạo ra Object bằng một thứ hai mặc dù nó vẫn còn "sống". Đây là hành vi không xác định.

1

Tôi tin rằng điều này được đưa vào tiêu chuẩn để cho phép thu gom rác thải. Và để chỉ ra rằng C++ hoạt động khác nhau mà một số ngôn ngữ khác, bằng cách không gọi destructors trong khi thu thập.

Nó đặc biệt nói rằng lưu trữ có thể được tái sử dụng mà không cần gọi destructors của các đối tượng trong khu vực bộ nhớ đó. Nếu chương trình phụ thuộc trên các trình phá hủy đang chạy, nó sẽ không hoạt động như mong đợi.

Nếu số không phụ thuộc vào trình phá hủy, tất cả đều ổn.

3

Trong trường hợp này, chúng tôi có câu trả lời chính xác. Dòng cụ thể đã được giới thiệu để giải quyết CWG 1116, "Bí danh của các thành viên công đoàn".

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