2012-03-31 28 views
8

Trình hủy mặc định trong các lớp C++ có tự động xóa các thành viên không được cấp phát rõ ràng trong mã không? Ví dụ:mức phá hoại mặc định làm

class C { 
    public: 
    C() {} 
    int arr[100]; 
}; 

int main(void) { 
    C* myC = new C(); 
    delete myC; 
    return 0; 
} 

Liệu xóa myC có thể tự động xử lý arr của tôi không? Hay tôi có cần viết bản hủy diệt của C để làm điều này một cách rõ ràng không?

+2

http://www.parashift.com/c++-faq-lite/dtors.html – Anycorn

+0

nó sẽ tự động xóa mảng đó. – JosephH

Trả lời

5

Hàm khởi tạo (trong trường hợp không có bất kỳ ctor-initializer-list) nào gọi hàm tạo mặc định cho từng đối tượng con.

Vì bạn không có các lớp cơ sở và các biến thành viên của bạn là các kiểu nguyên thủy, nó sẽ không làm gì cả.

Tương tự với trình phá hủy. Yours là trình biên dịch ngầm được tạo ra từ khi bạn chưa khai báo một trình biên dịch, và nó sẽ gọi hàm hủy cho mỗi subobject. Một lần nữa đó là tầm thường bởi vì subobject duy nhất của bạn là một tập hợp các nguyên thủy.

Bây giờ, tất cả bộ nhớ của lớp sẽ được giải phóng khi bạn xóa nó. Vì mảng được nhúng bên trong lớp, nó là một phần của cùng vùng bộ nhớ và sẽ được giải phóng cùng một lúc.

+0

@Mark: Không có sự phân biệt "mặc định" cho các trình phá hủy, vì chúng không thể bị quá tải. –

+0

@Mark: Không sao cả. –

+0

Bởi "subobject", bạn có nghĩa là "thành viên dữ liệu", chắc chắn? –

5

Trình phá hủy ngầm định (mặc định) sẽ gọi hàm hủy cho từng thành viên. Trong trường hợp mảng thành viên, nó sẽ gọi hàm hủy cho mỗi phần tử của mảng.

Lưu ý rằng con trỏ không có trình phá hủy; bạn cần xóa chúng theo cách thủ công. Bạn không có vấn đề này trong ví dụ được cung cấp, nhưng nó là một cái gì đó để được nhận thức.

+1

Con trỏ có loại destructors [(xem tại đây)] (http://ideone.com/97iUx), mặc dù rõ ràng là chúng không xóa những gì chúng trỏ đến. – Pubby

+0

chờ ... bạn nói con trỏ không có destructors, nhưng tôi nghĩ rằng xóa chỉ mất một con trỏ. bạn đang nói rằng destructor mặc định sẽ gọi xóa trên mỗi 100 ints trong mảng? – Robz

+0

@Robz, Không - tôi đang nói là trình phá hoại ngầm * không * gọi xóa, bạn phải tự mình làm điều đó trong một trình phá hoại rõ ràng nếu bạn có bất kỳ con trỏ thô nào làm thành viên. –

5

Nếu lớp/cấu trúc của bạn có chứa một con trỏ, và bạn phân bổ một cách rõ ràng một cái gì đó cho con trỏ đó để tham khảo, sau đó bạn thường cần phải viết một kết hợp delete trong dtor. Các thành viên được nhúng trực tiếp vào lớp/cấu trúc sẽ được tạo và hủy tự động.

class X { 
    int x; 
    int *y; 
public: 
    X() : y(new int) {} 
    ~X() : { delete y; }  
}; 

Tại đây X :: x sẽ được tạo/hủy tự động. X :: y (hoặc, về mặt kỹ thuật chính xác, những gì X :: y điểm tại) sẽ không - chúng tôi phân bổ nó trong ctor và phá hủy nó trong dtor.

+0

'X :: y' bị phá hủy tự động. Đó là' * (X :: y) 'có thể bị rò rỉ nếu nó không bị phá hủy. (Và mẫu của bạn vi phạm Quy tắc-của-Ba/Bốn/Năm) –

+0

@BenVoigt: Có - câu hỏi là về những gì các destructor không, không phải làm thế nào để viết một lớp học mà xử lý chính xác quyền sở hữu từ xa –

0

Bất kỳ nội dung nào bạn gọi mới đều phải xóa tương ứng. Nếu bạn không gọi mới để tạo ra một thể hiện của một cái gì đó thì bạn không phải gọi xóa.

+0

IMHO, bạn hiếm khi nên 'xóa' bất cứ điều gì trong ứng dụng mã. thành viên của ngữ nghĩa cho tất cả các thành viên, như vậy mà hủy diệt tự động không lừa. Nếu điều đó không thành công, con trỏ thông minh thường là một lựa chọn tốt hơn cho các con trỏ thủ công và 'xóa'. – Rawler

-1

Bạn không phải viết trình phá hủy. Lớp C++ có hàm hủy mặc định để xóa đối tượng sau khi 'trả về 0' để tái chế bộ nhớ.

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