2016-10-01 15 views
13

goto hoặc switch có thể nhảy qua tuyên bố tuyên bố vì nó không có bộ khởi tạo và việc xây dựng là tầm thường - và đối tượng cũng là tầm thường có thể hủy.Khi nhảy qua một tuyên bố, tại sao là cần thiết tầm thường?

Lý do cơ bản cho ràng buộc trên destructor là gì?

struct trivial { 
    trivial() = default; 
    ~ trivial() = default; 
}; 

struct semi_trivial { 
    semi_trivial() = default; 
    ~ semi_trivial() noexcept { do_something(); } 
}; 

void foo() { 
    goto good_label; // OK 
    trivial foo; 
good_label: 

    goto bad_label; // Error: this goto statement 
    semi_trivial bar; // cannot jump over this declaration. 
bad_label: 

    std::cout << "hi\n"; 
} 

Trả lời

5

Từ ngữ hiện tại là kết quả của N2762. Bài viết cung cấp cho các lý do sau đây:

6,7 stmt.dcl:

    Nhảy trên định nghĩa của một biến tự động sẽ đặt ra vấn đề liệu các destructor cho biến đó phải được chạy ở phần cuối của khối. Do đó, destructor cần phải tầm thường, tức là không có hiệu lực. Tương tự, hàm khởi tạo mặc định (cái có khả năng được sử dụng để khởi tạo đối tượng) cũng được yêu cầu để không làm bất cứ điều gì, tức là tầm thường. Không có yêu cầu nào khác là cần thiết.

Tôi nghĩ trường hợp cần lưu ý là:

int i = 2; 
switch (i) { 
    case 1: 
    semi_trivial st; 
    do_something(st); 
    break; 
    case 2: 
    break; // should st be destructed here? 
} 

Và quả thực, đây không phải là một câu hỏi dễ trả lời. Kêu gọi destructor sẽ không phải là điều rõ ràng nhất để làm. Không có cách nào tốt để nói liệu nó có nên được gọi hay không. Biến số st ở đây chỉ được sử dụng trong các câu lệnh case 1 và các lập trình viên sẽ ngạc nhiên nếu hàm hủy của nó được gọi bởi câu lệnh break của case 2 mặc dù nó hoàn toàn không được sử dụng ở đó và không được xây dựng.

+0

@Barry Lần đầu tiên 'ngắt;' không bao giờ được thực thi, vì 'i' có giá trị' 2'. Câu hỏi đặt ra là liệu * giây * 'ngắt;' có nên hủy 'st', mặc dù nó không được khởi tạo và không được sử dụng trong câu lệnh' case 2'. Không có từ ngữ đặc biệt để ngăn chặn nó, nó sẽ bị phá hủy, nhưng phá hủy nó có thể không phải là điều đúng đắn để làm. Do đó việc cấm nhảy tới 'trường hợp 2'. – hvd

+0

Ah, vâng. Nên thêm tất cả điều đó vào câu trả lời. – Barry

+0

Cảm ơn! Đọc giữa các dòng, bài báo dường như đang nói rằng destructor sẽ chạy nếu hàm tạo tầm thường được chạy theo lý thuyết. Đối với tôi, nếu đối tượng có thể được sử dụng trong phạm vi, sau đó nó được xây dựng một cách hiệu quả, và destructor chắc chắn sẽ được chạy. Hmmm… – Potatoswatter

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