2010-07-05 26 views
37

Xét đoạn mã sau:Goto ra khỏi một khối: làm destructors được gọi là?

void foo() 
{ 
    { 
     CSomeClass bar; 

     // Some code here... 

     goto label; 

     // and here... 
    } 

label: 
    // and here... 
} 

sẽ destructor của thanh được gọi là?

+0

Tại sao bạn cần biết điều này? 'goto' có ý nghĩa trong mã được tạo ra, nhưng ở đó bạn có thể và nên tránh các đối tượng với destructors anyway. – MSalters

+13

@MSalters: mà doesnt làm cho sence ở tất cả, tại sao bạn nên tránh các đối tượng với destructors? –

+1

@Viktor: Hãy để tôi mở rộng phần thứ hai của câu: _In create code_, bạn có thể và nên tránh các đối tượng với destructors anyway. Việc sử dụng kinh điển của 'goto' là trong mã FSM được tạo. Ở đây nhảy xảy ra ngược và tiến, mà không quan tâm đến các trạng thái mã trạng thái chỉ xảy ra ở giữa. Các trạng thái FSM không đơn giản là tuyến tính, nhưng phải có mã C++. – MSalters

Trả lời

52

CáC++ chuẩn C nói:

Mở lối ra từ một phạm vi (tuy nhiên tài năng), hủy (12,4) là gọi cho tất cả các đối tượng xây dựng với thời gian tự động lưu trữ (3.7.2) (tên o bửa hoặc thời gian) được khai báo trong phạm vi đó, trong thứ tự đảo ngược của tuyên bố của chúng.

Vì vậy, câu trả lời là "có".

+0

Cảm ơn. Đó là những gì tôi cần. –

9

1) Có. 2) Không làm điều này.

Sự cộng tác: về mặt khái niệm, điều này không khác gì khi rời khỏi vòng lặp qua break. Tuy nhiên, goto là mạnh mẽ, không khuyến khích mạnh mẽ. Nó gần như không bao giờ cần thiết để sử dụng goto, và sử dụng bất kỳ nên được xem xét kỹ lưỡng để tìm hiểu những gì đang xảy ra.

+0

Câu trả lời hoàn hảo. – Mizipzor

+1

2) bạn làm điều này khi bạn thoát khỏi vòng thực sự. –

+14

Thực ra, goto có ý nghĩa trong một vài trường hợp. –

21

Có, họ sẽ được gọi.

Cập nhật: (.. Nó okay để làm điều này, gotos là không thua kém ném ngoại lệ giả hoặc sử dụng bools/ifs thoát ra khỏi những thứ Một goto đơn giản bên trong một hàm không làm cho nó mã spaghetti)

+7

+1 để phủ nhận sinh viên tự cao, những người cảm thấy cần phải downvote vì cá nhân họ nghĩ rằng gotos là xấu. Gotos có sử dụng hợp lệ, mọi người, bất kể những gì các giáo sư của bạn đã nói với bạn. – KevenK

+2

"nó không quan trọng để làm điều này, gotos không tồi tệ hơn ném giả ngoại lệ hoặc sử dụng bools/ifs để có được ra khỏi sự vật" Ném một ngoại lệ giả là một cách khủng khiếp để làm điều này (ném ngoại lệ nói chung là cực kỳ tốn kém) và nếu nó giữa đó và gotos, tôi chắc chắn thích gotos. Tuy nhiên, chức năng viết cho những trường hợp này chắc chắn là cách tốt nhất để đi. – stinky472

+1

@KevinK - Gotos có thể sử dụng hợp lý trong lý thuyết, nhưng chúng cực kỳ hiếm trong thực tế. Tôi sẽ lập luận rằng nếu có vẻ như bạn phải sử dụng một goto, tình hình ít nhất là xứng đáng kiểm tra chặt chẽ. Và đối với những người phát triển ban đầu, tôi đề nghị tránh chúng là một kỷ luật tốt để học hỏi. – jwismar

4

Có, như mọi người khác nói. C++ quy định/ủy nhiệm điều này.

Nhưng chỉ để thêm vào đó, cho đầy đủ: nếu goto của bạn sử dụng các phần mở rộng goto computed- tìm thấy trong một số trình biên dịch - gcc, kêu vang, có thể những người khác nhưng không bao gồm MSVC cuối cùng tôi biết - hay không đối tượng của destructor sẽ được gọi là khá mơ hồ. Khi một số goto chuyển đến một địa điểm duy nhất, nó rất rõ ràng những gì destructors phải được gọi trước khi kiểm soát dòng chảy chuyển giao. Nhưng với tính toán goto, các trình phá hủy khác nhau có thể cần phải được gọi động, để cung cấp cho các ngữ nghĩa "dự kiến". Tôi không chắc chắn những gì trình biên dịch thực hiện phần mở rộng này làm, trong những trường hợp. Bộ nhớ của tôi khi gặp phải điều này là clang cảnh báo khi một tính toán-goto có thể để lại một phạm vi với một đối tượng có một destructor không trival, tuyên bố destructor sẽ không được gọi. Trong một số trường hợp có thể là tốt, trong những trường hợp khác thì không. Tôi không biết những gì các trình biên dịch khác làm. Chỉ cần nhận thức được vấn đề nếu bạn muốn sử dụng tính toán goto s trong buổi hòa nhạc với các đối tượng với các destructors không tầm thường.

+0

Cảm ơn. Tôi chỉ sử dụng gotos tính từ C, và trong những tình huống rất hiếm. –

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