2012-08-01 64 views
8

Từ các tài liệu cpp cho std::vector, tôi thấy điều này:C++ STL Vector: push_back dùng tham khảo

void push_back (const T& x); 

Tôi hiểu rằng push_back tạo một bản sao của đối tượng mà tôi vượt qua. Nhưng, tại sao là chữ ký const T& ? Bằng cách nhìn vào điều này, ban đầu tôi nghĩ rằng nó có một tham chiếu const của bất kỳ đối tượng mà tôi đẩy đến vector.

+0

Tôi sẽ làm điều đó. Tôi nhận ra nó chỉ ngày hôm qua và tôi đang làm nó từ đó trở đi. Cảm ơn bạn! – sachin2182

Trả lời

12

Các tùy chọn khác sẽ là

void push_back(T x); 

có nghĩa là, lấy x theo giá trị. Tuy nhiên, điều này sẽ (trong C++ 03) dẫn đến việc tạo thêm một bản sao của x (bản sao trong các đối số đến push_back). Lấy x bởi tham chiếu const tránh điều này.

Hãy nhìn vào ngăn xếp cho một cuộc gọi v.push_back(T()) lấy theo giá trị:

v.push_back(T());      // instance of T 
void std::vector<T>::push_back(T x) // copy of T 
new (data_[size_ - 1]) T(x)   // copy of copy of T 

Lấy bằng cách tham chiếu const chúng tôi nhận được:

v.push_back(T());        // instance of T 
void std::vector<T>::push_back(const T &x) // const reference to T 
new (data_[size_ - 1]) T(x)     // copy of T 

Trong C++ 11 nó sẽ có thể (mặc dù không cần thiết) để lấy x theo giá trị và sử dụng std::move để di chuyển nó lên vectơ:

v.push_back(T());        // instance of T 
void std::vector<T>::push_back(T x)   // copy of T 
new (data_[size_ - 1]) T(std::move(x))  // move the copy of T 
+1

Nó vẫn còn thích hợp hơn để có nó mất 'T const &' trong C++ 11 (cùng với một 'T &' 'quá tải), như không phải tất cả các đối tượng có thể được di chuyển hiệu quả. –

7

Số object bạn đẩy được chuyển bằng tham chiếu để tránh extra copy. Hơn một bản sao được đặt trong vector.

7

Chỉ cần làm rõ "bản sao bổ sung" @ecatmur mô tả, nếu push_back nhận được đối số của nó theo giá trị, điều sẽ xảy ra là bạn sẽ bắt đầu với đối tượng của mình. Một bản sao đó sẽ được chuyển đến push_back làm thông số của nó. Sau đó, push_back sẽ tạo một bản sao của rằng để đưa vào chính vectơ.

Vì việc triển khai thực tế push_back nhận đối số của nó bằng tham chiếu, nó (push_back) tạo đối tượng mới trong vectơ trực tiếp dưới dạng bản sao đối tượng gốc của bạn. Như đã đề cập, có, với C++ 11 sử dụng ngữ nghĩa di chuyển, nó sẽ có thể (mặc dù có lẽ không đặc biệt thuận lợi) để chuyển đối số theo giá trị, và sau đó di chuyển giá trị từ đối số đó vào đối tượng mới trong vectơ. Nếu những gì bạn đặt trong vectơ là, một chuỗi chỉ chứa một con trỏ và một vài trường "giữ sách" (lượng bộ nhớ được phân bổ, lượng bộ nhớ hiện đang sử dụng), sẽ là gần như là hiệu quả khi chuyển một tham chiếu, bởi vì một động tác chỉ có thể làm một bản sao nông - sao chép con trỏ và tự giữ các giá trị, thay vì tất cả các dữ liệu mà nó trỏ vào. Tuy nhiên, nếu đối tượng được đề cập giữ tất cả dữ liệu của nó trực tiếp (tức là, không phải là một con trỏ), thì di chuyển sẽ chậm như một bản sao.

Chuyển qua tham chiếu, tránh tất cả sao chép đó, vì vậy ngay cả đối với nội dung nào đó như chuỗi, nó vẫn nhanh hơn (đối với trường hợp như vậy đối tượng gốc không thể bị vô hiệu). Nó cũng có lợi thế nhỏ khi làm việc với C++ 98/03, không chỉ C++ 11.

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