2012-01-28 55 views
6

Xét đoạn mã sau:Destructor không được gọi khi một ngoại lệ được ném

#include <iostream> 
using namespace std; 

class Test { 
    static int count; 
    int id; 
public: 
    Test() { 
    count++; 
    id = count; 
    cout << "Constructing object number " << id << endl; 
    if(id == 4) 
     throw 4; 
    } 
    ~Test() { cout << "Destructing object number " << id << endl; } 
}; 

int Test::count = 0; 

int main() { 
    try { 
    Test array[5]; 
    } catch(int i) { 
    cout << "Caught " << i << endl; 
    } 
} 

Đoạn mã trên sẽ cho kết quả như sau:

Constructing object number 1 
Constructing object number 2 
Constructing object number 3 
Constructing object number 4 
Destructing object number 3 
Destructing object number 2 
Destructing object number 1 
Caught 4 

Tôi nghĩ destructors luôn gọi khi đối tượng trở ra khỏi phạm vi , ngay cả khi ngoại lệ được ném. Tại sao không phải là một trong những kẻ hủy diệt Test trường hợp được gọi trong trường hợp này?

+0

Tôi đã chỉnh sửa câu hỏi của bạn thành một thứ phù hợp hơn cho Stack Overflow. Vui lòng thực hiện theo [các nguyên tắc câu hỏi] (http://stackoverflow.com/questions/how-to-ask) để tham khảo trong tương lai hoặc câu hỏi của bạn có thể bị downvoted/closed. –

Trả lời

8

Bạn đang tạo một mảng của 5Test đối tượng nhưng bạn ném một ngoại lệ sau khi bạn tạo 3hoàn đối tượng, Trường hợp ngoại lệ được ném trong khi ở các nhà xây dựng của đối tượng thứ 4. Việc xây dựng đối tượng thứ 4 không hoàn thành cho đến khi kết thúc đóng ngoặc của hàm khởi tạo.

Ngăn xếp hủy bỏ các đối tượng được xây dựng theo thứ tự ngược lại mà chúng được tạo ra, vì đối tượng thứ 45 không bao giờ được xây dựng.

Quy tắc ngoại lệ là:
Khi ngoại lệ được ném hủy cho tất cả đối tượng được tạo hoàn toàn trong phạm vi đó sẽ được gọi.
Một đối tượng được tạo hoàn toàn là đối tượng có hàm tạo được gọi là sạch mà không có bất kỳ ngoại lệ nào.

+0

Bài viết [Guru of the Week (# 66)] (http://www.gotw.ca/gotw/066.htm) đặc biệt liên quan đến tình huống này. –

+0

tắt bởi một - chỉ có 3 đối tượng được xây dựng hoàn chỉnh, do đó chỉ có 3 trình phá hủy được gọi. –

+0

@ChrisDodd: Được phát hiện tốt. Tôi đã đọc sai dấu vết. –

3

Thay vì writting tuyên bố cout sau id = count như đã đề cập dưới đây: -

id = count; 
    cout << "Constructing object number " << id << endl; 
    if(id == 4) 
    throw 4; 

bạn nên đã viết nó sau khi tuyên bố ném. Điều đó sẽ mang lại cho bạn bức ảnh tốt hơn về những gì đã xảy ra. Như thế này: -

Test() { 
count++; 
id = count; 
if(id == 4) 
    throw 4; 
cout << "Constructing object number " << id << endl; 
    } 

Các o/p sẽ là: - Xây dựng số đối tượng 1 Xây dựng số đối tượng 2 Xây dựng đối tượng số 3 huỷ số đối tượng 3 huỷ số đối tượng 2 số đối tượng huỷ 1 Bị bắt 4

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