2010-10-08 25 views
7

chỉ là một câu hỏi nhanh. Có sự khác biệt giữaCác khối thử chức năng, nhưng không phải trong các nhà xây dựng

void f(Foo x) try 
{ 
    ... 
} 
catch(exception& e) 
{ 
    ... 
} 

void f(Foo x) 
{ 
    try { ... } 
    catch (exception& e) 
    { 
     ... 
    } 
} 

?

Nếu không, tại sao chức năng thử chặn cho (trường hợp danh sách khởi tạo cho các nhà thầu được đặt sang một bên)? Điều gì sẽ xảy ra nếu người tạo bản sao của Foo ném ngoại lệ khi x được chuyển đến f?

Trả lời

9

Các khối thử chức năng chỉ cần thiết trong các nhà thầu. Trong tất cả các trường hợp khác, chính xác cùng một hiệu ứng có thể đạt được bằng cách bao quanh toàn bộ phần thân của hàm trong khối try/catch bình thường.

Nếu trình tạo bản sao được sử dụng để khởi tạo tham số sẽ ném ngoại lệ, điều này xảy ra trước cuộc gọi hàm. Nó không thể bị bắt bởi một hàm try block hoặc xử lý đặc biệt trong hàm như hàm không được gọi.

+5

Có nghĩa là chức năng mà cố gắng khối cho các chức năng phi constructor là JUST một sự thay thế cú pháp, không có mục đích ngữ nghĩa, mà thực sự có thể là một lập luận có thể tranh cãi cho sự tồn tại của chúng. Mặt khác, có quá nhiều thứ không thể giải thích trong C++, ngay cả trong số những thứ không liên quan gì đến khả năng tương thích. –

1

Các khối thử chức năng được thêm rõ ràng cho mục đích bắt ngoại lệ trong danh sách khởi tạo của hàm dựng.

Trong ví dụ của bạn không có khởi tạo hàm tạo, do đó không có sự khác biệt giữa hai biểu mẫu.

+0

không giải quyết được vấn đề của các đối tượng tĩnh/toàn cầu của các lớp có khả năng ném-in-constructor, bởi vì ngoại lệ cũng được rethrown. –

+2

@Armen: Constructors _have_ để ném nếu đối tượng không thể được khởi tạo. Đây là cách _only_ để báo cáo lỗi xây dựng. –

5

Một số điều được cho phép bởi vì sẽ khó khăn hơn để không cho phép chúng. Cho phép chức năng thử khối trên một số, nhưng không phải tất cả các cơ quan chức năng sẽ làm cho ngữ pháp và trình biên dịch phức tạp hơn.

+0

Điểm tốt, đó là những gì tôi nghĩ đầu tiên. –

3

Chỉ cần phát hiện một điểm thú vị trong Dr. Dobb's article này (mặc dù khá cũ):

... hãy nhớ rằng bạn không thể trả về một giá trị bên trong một handler chức năng-thử-block. Vì vậy, nó làm cho không có cảm giác sử dụng một khối chức năng thử cho một tổ chức phi void function

và đây là ví dụ mã của họ:

int f() 
try 
{ 
    ... 
} 
catch(Error &e) 
{ 
    // oops, can't return int from here! 
} 

nào thực sự có nghĩa là chức năng mà cố gắng khối là yếu hơn " thường xuyên "thử khối và sử dụng của họ nên được nản lòng khác hơn là trong các nhà xây dựng.

(bài viết là từ năm 2000, vì vậy nó sẽ được tốt đẹp nếu ai đó sẽ bình luận về việc liệu đây vẫn là như vậy trong các tiêu chuẩn hiện hành)

+1

... trừ khi khối "bắt" chính nó ném vô điều kiện hoặc quay lại, trong trường hợp đó khối thử chức năng là cách sạch nhất để viết này, IMO. – Nemo

+2

(Nhận xét được thêm 5 năm sau :) Tôi đã thử nghiệm với gcc 5.4 - Ở đó, tôi có thể trả về một giá trị từ khối catch. Tuy nhiên, tôi không học bất kỳ tiêu chuẩn nào. – ralfg

+1

Câu trả lời này là sai và AFAIK đã được như vậy tại thời điểm tạo ra, xem [ở đây] (http://en.cppreference.com/w/cpp/language/function-try-block), đặc biệt là ví dụ tại đáy. – Walter

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