Sự khác biệt giữa c[i]
và c.at(i)
là at()
ném std::out_of_range
ngoại lệ nếu i
nằm ngoài phạm vi của vector, trong khi operator[]
chỉ đơn giản gọi hành vi undefined, có nghĩa là bất cứ điều gì có thể xảy ra.
Không ai nói at()
là tốt hơn operator[]
. Nó chỉ phụ thuộc vào hoàn cảnh. Như at()
thực hiện kiểm tra phạm vi, nó có thể không được mong muốn luôn luôn, đặc biệt là khi mã của bạn chính nó đảm bảo rằng chỉ số không bao giờ có thể rơi ra ngoài phạm vi. Trong những trường hợp như vậy, operator[]
là tốt hơn.
xem xét vòng lặp sau:
for(size_t i = 0 ; i < v.size(); ++i)
{
//Should I use v[i] or v.at(i)?
}
Trong một vòng lặp như vậy, operator[]
luôn luôn là một lựa chọn tốt hơn so với at()
hàm thành viên.
Tôi thích at()
khi tôi muốn nó ném ngoại lệ trong trường hợp chỉ mục không hợp lệ, để tôi có thể thực hiện công việc thay thế trong khối catch{ ...}
. Exceptions giúp bạn tách mã bình thường từ các mã đặc biệt/alternative như:
try
{
size_t i = get_index(); //I'm not sure if it returns a valid index!
T item = v.at(i); //let it throw exception if i falls outside range
//normal flow of code
//...
}
catch(std::out_of_range const & e)
{
//alternative code
}
Ở đây bạn có thể kiểm tra i
chính mình, để đảm bảo rằng nó là một chỉ số hợp lệ, và sau đó gọi operator[]
thay vì at()
, nhưng nó sẽ kết hợp mã bình thường với mã thay thế bằng cách sử dụng khối if-else
khiến việc đọc mã vạch khó đọc là . Nếu bạn thấy ở trên, try-catch
cải thiện khả năng đọc mã, vì nó thực sự tách mã bình thường khỏi mã thay thế, dẫn đến mã gọn gàng và sạch sẽ.
"Sự khác biệt là gì?" là một câu hỏi hay. Câu trả lời là: 1) kiểm tra phạm vi tự động (.at() sẽ ném một ngoại lệ ngoài phạm vi, [] sẽ không âm thầm), và 2) sở thích cá nhân - bạn thích cú pháp nào tốt hơn. "Cái nào tốt hơn?", Mặt khác là một phán đoán giá trị. Câu trả lời nhất thiết là "Nó phụ thuộc". IMHO ... – paulsm4
Không ai tốt hơn, họ phục vụ mục đích _similar nhưng khác nhau. –