2012-06-23 22 views
29

Nếu tôi muốn nhận được một giá trị trong vector, tôi có thể sử dụng hai tùy chọn: sử dụng toán tử []. Hoặc tôi có thể sử dụng chức năng .at ví dụ cho việc sử dụng:Tại sao sử dụng "vector.at (x)" tốt hơn "vector [x]" trong C++?

vector<int> ivec; 
ivec.push_back(1); 

Bây giờ tôi có thể thực hiện cả hai điều

int x1 = ivec[0]; 
int x2 = ivec.at(0); // or 

Tôi nghe nói sử dụng tại là một lựa chọn tốt hơn bởi vì khi tôi sử dụng tùy chọn mà tôi có thể ném này một trong một ngoại lệ.

Ai đó có thể giải thích điều này?

+3

"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

+11

Không ai tốt hơn, họ phục vụ mục đích _similar nhưng khác nhau. –

Trả lời

54

Sự khác biệt giữa c[i]c.at(i)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ẽ.

+4

"Không ai nói' at() 'là tốt hơn" - ha! Bạn sẽ ngạc nhiên. –

+0

@KonradRudolph: Cái gì? – Nawaz

+7

Đừng đánh giá thấp số lượng kẻ ngốc đang ở ngoài đó, và có bao nhiêu người trong số họ dạy C++. ;-) –

10

Sự khác biệt duy nhất giữa at[]at thực hiện kiểm tra phạm vi và [] thì không. Nếu bạn đã kiểm tra phạm vi đã hoặc đã xây dựng chỉ mục của mình theo cách không thể thoát khỏi phạm vi và cần phải truy cập một mục nhiều lần, bạn có thể lưu một vài chu kỳ CPU bằng cách chọn [] thay vì at.

Ví dụ về một tấm séc duy nhất và nhiều truy cập:

size_t index = get_index(vect); 
if (index < 0 || index >= vect.size()) return; 
if (vect[index] > 0) { 
    // .... 
} else if (vect[index] > 5) { 
    // .... 
} else .... 

Ví dụ về một trường hợp khi chỉ số được xây dựng để được bên trong giới hạn:

for (size_t i = 0 ; i != vect.size() ; i++) { 
    if (vect[i] > 42) { 
     // .... 
    } 
} 
0

Những câu trả lời khác là hoàn toàn chính xác, nhưng có thể tạo ấn tượng rằng bạn nên sử dụng at() khi viết mã mà bạn vẫn sẽ gỡ lỗi, vì điều đó sẽ gây ra lỗi khi được báo hiệu. Đây là trường hợp nói chung, nhưng không áp dụng cho hầu hết các trình biên dịch phổ biến - gcc có thể được thiết lập để thực hiện (kiểm tra phạm vi) phạm vi bằng putting it in debug mode và một cái gì đó tương tự có thể có thể được thực hiện trong Visual Studio.

0

Phương pháp vector C++ .at kiểm tra giới hạn do đó khi phần tử không tồn tại trong vectơ và ngoại lệ out_of_range được ném.

Khi sử dụng [] không kiểm tra giới hạn được thực hiện trên vectơ, do đó, nếu phần tử không tồn tại, không có ngoại lệ được ném và kết quả là hành vi không xác định như có giá trị ngẫu nhiên không có elemnts hiện có trong vectơ.

Sử dụng [] tốt hơn at về mặt an toàn tuy nhiên điều này sẽ đòi hỏi nhiều thời gian hơn và có tác động đến sự perfermance của chương trình.

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