Tại sao lại bắt một ngoại lệ là tham chiếu đến const?


84

Tôi đã nghe và đọc nhiều lần rằng tốt hơn nên bắt một ngoại lệ dưới dạng tham chiếu đến-hằng hơn là tham chiếu. Tại sao lại là:

try {
    // stuff
} catch (const std::exception& e) {
    // stuff
}

tốt hơn:

try {
    // stuff
} catch (std::exception& e) {
    // stuff
}

Câu trả lời:


67

Bạn cần:

  • một tham chiếu để bạn có thể truy cập ngoại lệ một cách đa hình
  • một const để tăng hiệu suất và nói với trình biên dịch rằng bạn sẽ không sửa đổi đối tượng

Cái sau không quan trọng nhiều bằng cái trước, nhưng lý do thực sự duy nhất để giảm const sẽ là để báo hiệu rằng bạn muốn thực hiện các thay đổi đối với ngoại lệ (thường chỉ hữu ích nếu bạn muốn cài đặt lại nó với ngữ cảnh được bổ sung vào cấp cao hơn) .


1
"nói với trình biên dịch rằng bạn sẽ không sửa đổi đối tượng" —Tôi cho rằng điều đó có thể hữu ích nếu bạn đang chuyển đối tượng dưới dạng tham số cho một lệnh gọi hàm.
Craig McQueen

1
ý bạn là gì khi 'truy cập vào ngoại lệ một cách đa hình'?
xoài

3
@mango có lẽ nó có nghĩa là để có thể gọi một hàm ảo (chẳng hạn như std::exception's what()chức năng). Nếu bạn bắt theo giá trị thì bạn không thể gọi hàm đó và lấy chi tiết ngoại lệ ban đầu.
MM

11
đã xem xét lắp ráp được sản xuất bởi apple clang 7 và gcc 5 (với tối ưu hóa O3) và tôi không thấy bất kỳ sự khác biệt nào giữa lắp ráp const ref và không const ref. Vì vậy, tôi đoán không có sự khác biệt trong việc tối ưu hóa cho gcc và apple
clang

2
Trình biên dịch có thể dễ dàng xem bạn sửa đổi đối tượng nào và đối tượng nào không ( SSA và sự lan truyền không đổi). Một lời giải thích tốt hơn là cần thiết (hoặc nó là một huyền thoại?).
gỉyx

31

Về cơ bản không có lý do gì cả.

Các đối tượng ngoại lệ sống trong không gian bộ nhớ của riêng chúng vì vậy bạn không phải lo lắng về việc bắt các ngoại lệ được tạo trong các biểu thức tạm thời.

Tất cả những gì bạn đang làm là hứa rằng bạn sẽ không sửa đổi đối tượng ngoại lệ, nhưng vì các đối tượng ngoại lệ nên có giao diện bất biến , nên thực sự không có gì thực tế ở đây.

Tuy nhiên, nó có thể làm cho bạn cảm thấy ấm áp và ấm cúng khi bạn đọc nó - đó là cách đối với tôi!

Chúng có ngăn xếp cục bộ, đặc biệt, riêng của chúng.
Disclaimer: Boost.Exception phá vỡ điều này để thực hiện những điều thú vị và thêm các chi tiết ngoại lệ, hậu xây dựng. Nhưng đây là hackery!


Bạn có thể vui lòng giải thích thêm về Exception objects live in their own memory space? Bạn có một bài đọc hay nào để gợi ý về nó?
Richard Dally,

@LeFlou: Tôi có thể chỉ cho bạn để tiêu chuẩn, nhưng nó muốn được một chút sai lầm khi xét thấy "một tốt đọc" ...: P
Lightness Races ở Orbit

Chắc chắn là có, sẽ rất thú vị khi tìm hiểu thêm về điều này từ quan điểm tiêu chuẩn. Tôi đang đọc Báo cáo kỹ thuật về Hiệu suất C ++ , bạn có tài liệu nào liên quan hơn không?
Richard Dally

@LeFlou: Vâng, nó không nhận được bất kỳ có thẩm quyền hơn so với tiêu chuẩn riêng của mình ....
Lightness Races ở Orbit

1
@RichardDally kiểm tra C ++ Primer 5th , § 18.1.1 Đối tượng loại trừ. Nó cho biết Đối tượng ngoại lệ nằm trong không gian, được quản lý bởi trình biên dịch, được đảm bảo có thể truy cập được với bất kỳ lệnh bắt nào được gọi. Đối tượng ngoại lệ bị phá hủy sau khi ngoại lệ được xử lý hoàn toàn.
Rick

5

Nó cho trình biên dịch biết rằng bạn sẽ không gọi bất kỳ hàm nào sửa đổi ngoại lệ, điều này có thể giúp tối ưu hóa mã. Có thể không tạo ra nhiều khác biệt, nhưng chi phí để làm điều đó cũng rất nhỏ.


2

bạn sẽ sửa đổi ngoại lệ? nếu không, nó cũng có thể là const. cùng lý do bạn NÊN sử dụng const ở bất kỳ nơi nào khác (tôi nói NÊN vì nó không thực sự tạo ra nhiều khác biệt trên bề mặt, có thể giúp ích cho trình biên dịch và cũng giúp người lập trình sử dụng mã của bạn đúng cách và không làm những thứ họ không nên làm)

các trình xử lý ngoại lệ, có thể là nền tảng cụ thể và có thể đặt các ngoại lệ ở những nơi vui nhộn vì họ không mong đợi chúng thay đổi?


-1

Vì lý do tương tự, bạn sử dụng một hằng số.


Và đối với những lý do tương tự như lý do tại sao để thích tài liệu tham khảo trên con trỏ :-)
Dimitri C.

12
Đơn giản và lấp lánh, nhưng không thực sự là một câu trả lời.
Omnifarious
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.