Tôi cho rằng lý do pop() không phải ném một ngoại lệ có không có gì để làm với hiệu quả hoặc hiệu suất, nhưng với - ngoại lệ.
Như người ta lập luận elsewhere:
SGI giải thích: http://www.sgi.com/tech/stl/stack.html Người ta có thể tự hỏi tại sao pop() trả về bãi bỏ, thay vì value_type. Tức là, tại sao phải sử dụng đầu() và pop() để kiểm tra và loại bỏ phần tử trên cùng, thay vì kết hợp hai thành phần trong một hàm thành viên đơn lẻ ? Trong thực tế, có là một lý do chính đáng cho thiết kế này. Nếu pop() trả về phần tử trên cùng, nó sẽ phải trả về giá trị thay vì so với tham chiếu: trả về theo tham chiếu sẽ tạo ra một con trỏ lơ lửng. Tuy nhiên, Trả lại theo giá trị, là không hiệu quả: nó liên quan đến ít nhất một cuộc gọi hàm sao chép dự phòng .Kể từ , không thể bật() trả lại giá trị theo cách sao cho cả hiệu quả và chính xác, nhiều hơn hợp lý để không trả lại giá trị tất cả và yêu cầu khách hàng sử dụng đầu () để kiểm tra giá trị ở đầu trang của ngăn xếp.
std :: stack < T> là mẫu. Nếu pop() trả về phần tử trên cùng, nó sẽ phải trả về giá trị thay vì so với tham chiếu theo giải thích ở trên giải thích. Điều đó có nghĩa là, ở phía người gọi , nó phải được sao chép theo một loại đối tượng T khác. Điều đó liên quan đến một nhà xây dựng bản sao hoặc sao chép chuyển nhượng cuộc gọi của nhà điều hành. Điều gì sẽ xảy ra nếu loại T này là đủ tinh vi và nó ném một ngoại lệ trong khi sao chép hoặc gán bản sao? Trong trường hợp đó, giá trị , nghĩa là hàng chồng (trả lại theo giá trị) chỉ đơn giản là bị mất và có không có cách nào khác để truy xuất nó từ ngăn xếp khi hoạt động pop của ngăn xếp là hoàn tất thành công!
Khi chúng tôi kết luận rằng nhạc pop nên không trở lại các yếu tố nó bật và do đó giao diện của nó là cố định như void pop()
, nó - là quan điểm của tôi này - không có ý nghĩa gì nữa để quy định những gì xảy ra khi pop() được gọi trên một ngăn xếp trống.
Lưu ý rằng tiêu chuẩn yêu cầu !empty()
làm điều kiện tiên quyết để gọi pop().
UncleBens (trong nhận xét) chắc chắn có điểm không kiểm tra điều kiện tiên quyết trong thời gian chạy (không bao giờ được quy định bởi C++ std AFAIK) có mùi hiệu suất nhất định. Tuy nhiên, để trích dẫn một phần của câu hỏi ban đầu: (tôi nhấn mạnh)
(Tôi đang thiết kế một Stack chuyên cho mã của riêng tôi và muốn biết cân bằng với phương pháp này (mà đòi hỏi một tự kiểm tra xem ngăn xếp rỗng) vs ném một ngoại lệ .
tôi sẽ lập luận, mà thực tế là pop()
không trả lại bất cứ điều gì làm cho câu hỏi tranh luận. Nó (IMHO) chỉ đơn giản doesn' t có ý nghĩa để buộc pop() để xác thực nếu ngăn xếp trống, khi chúng tôi thực sự không nhận được bất kỳ thứ gì từ nó (tức là nếu ngăn xếp sẽ trống pop() có thể chỉ đơn giản là một noop, đó là (thừa nhận) không được quy định bởi Std hoặc).
Tôi nghĩ người ta có thể hỏi tại sao top()
không ném ngoại lệ hoặc người ta có thể hỏi tại sao pop()
không trả về phần tử trên cùng. Nếu pop
không trả lại bất cứ điều gì, ném một ngoại lệ không có ý nghĩa (trong thế giới C++) - Tuyên bố rằng nó không ném một ngoại lệ "vì các chi phí thời gian chạy của trường hợp ngoại lệ" như câu trả lời khác dường như ngụ ý là - IMHO - thiếu điểm.
Nguồn
2011-02-03 22:10:46
Bạn đã đoán gần đúng. Nó không phải là chi phí của trường hợp ngoại lệ đó là vấn đề. Nó sẽ kiểm tra nếu ngăn xếp trống mỗi lần. Nếu bạn sử dụng std :: stack, bạn sẽ được biết (hoặc tự kiểm tra) khi nó trống. –
Tôi không chắc mình hiểu cách kiểm tra ngăn xếp trống trước khi mỗi cửa sổ bật lên không hiệu quả. Nó sẽ là một so sánh hằng số rất nhỏ để thực hiện, đúng không? – PlagueHammer
@Nocturne: Nó sẽ nhỏ, nhưng nó vẫn sẽ là một cái gì đó. Cái gì> Không có gì. Điều đó nói rằng, std :: stack là một adapter container, do đó, nó chỉ làm bất cứ điều gì container tiềm ẩn trong trường hợp này. –