Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Temporaray object
- ==================
- Đối tượng tạm là 1 khái niệm rất thông dụng và nó xuất hiện trong phần lớn các câu lệnh mà chúng ta viết
- ```cpp
- int a=4+(3*b);
- ```
- Ở dòng code trên, chương trình cần sử dụng 2 đối tượng tạm ( gọi chung cho cả biến tạm và giá trị tạm)
- Phân tích rõ hơn việc sd 2 đối tượng tạm trong code trên:
- ```cpp
- int temp1=3*b;
- int temp2=4+temp1;
- int a=temp2;
- ```
- Hai đoạn code trên sẽ ko khác nhau mấy về chi phí thực thi. Chỉ khác ở chỗ đoạn code đầu, chương trình sử
- dụng temporary object, còn đoạn thứ hai ta sử dụng named object để chứa giá trị tạm.
- Ta thường sẽ gặp các loại đối tượng sau:
- -Giá trị trung gian trong quá trình tính toán biểu thức. vd int a=4+(3*b);
- -Biến trả về từ hàm.
- ```cpp
- std::vector<int> sortedArray=createSortedArray(intputedArray);
- ```
- -Biến được khởi tạo nhưng ko đặt tên.
- ```cpp
- if(string("dieuninh")==string("xinhgai"));
- ```
- Trong đonạ code này, ta tạo ra đối tượng string để chứa giá trị "dieuninh" và "xinhgai" nhưng vì ko đặt tên
- nên 2 đối tượng này là 2 đối tượng tạm.
- =>Đối với những chương trình nhỏ thì có thể ta không để ý. Nhưng đối với những chương trình lớn,
- việc tạo ra các đối tượng tạm tốn rất nhiều chi phí. Do đó, từ C++11 đã được đưa vào thêm 2 khái
- niệm mới "rvalue reference" và "move semantic" để giúp giải quyết, tối ưu và giảm thiểu chi phí
- cho việc copy trạng thái (dữ liệu) của đối tượng tạm.
- #lvalue, rvalue và lvalue reference
- =============
- lvaule và rvalue
- -------------
- ```cpp
- C++11’s most pervasive feature is probably move semantics, and the foundation of
- move semantics is distinguishing expressions that are rvaluesfrom those that are lval‐
- ues. That’s because rvalues indicate objects eligible for move operations, while lvalues
- generally don’t. In concept (though not always in practice), rvalues correspond to
- temporary objects returned from functions, while lvalues correspond to objects you
- can refer to, either by name or by following a pointer or lvalue reference.
- <trích từ ebook Effective Morden C++ của Scott Meyers>
- ```
- Đọc giải thích ở sách t.anh có vẻ khó hiểu.
- Thật sự thì khái niệm lvalue và rvalue cũng ko có 1 định nghĩa rõ ràng, nhưng chúng ta có 1 thủ thuật để nhận biết nó
- là bạn hãy đặt giá trị mà bạn cần kiểm tra ở bên trái dấu "=" (thực hiện gán giá trị cho nó).
- Nếu nó thực hiện được và ko báo lỗi thì nó là lvalue. Ngược lại , nếu compiler
- báo lỗi "lvalue required as left operand of assignment" thì chắc chắn giá trị đó là rvalue.
- Vậy ta có thể hiểu lvalue là giá trị có thể gán được, còn rvalue là giá trị ko thể
- gán được hoặc rvalue chỉ có thể nằm bên phải dấu "=". Ta có thể thực hiện lấy địa chỉ của lvalue sủ dụng toán tử '&'
- nhưng ko thể lấy địa chỉ của rvalue.
- ```cpp
- //dream là 1 lvalue do phép gán bên dưới thành công;
- string dream="I can make it";
- // doNothing*beRich là 1 rvalue vì compiler sẽ báo lỗi dòng này
- int doNothing=1, beRich=2;
- (doNothing*beRich)=8;
- ```
- Ta còn có 1 cách khác để định nghĩa lvalue và rvalue một cách dễ hiểu hơn, đó là
- dựa vào vòng đời của "giá trị". Vùng nhớ chứa giá trị rvalue có vòng đời rất ngắn, nó sẽ bị hủy ngay khi biểu
- thức kết thúc. Còn vùng nhớ chứa giá trị lvalue có vòng đời dài hơn, và nó chỉ bị hủy
- khi ra khỏi phạm vi định nghĩa của nó.
- ```cpp
- int main()
- {
- int b=2;
- //giả sử có 2 biến tạm temp1=3*b và temp2=4+temp1 được tạo ra
- //hủy temp1 và temp2 vì đã kết thúc biểu thức a=4+(3*b) chứa nó
- int a=4+(3*b);
- a=3;
- //hủy a,b
- }
- ```
- Khái quát hơn, ta có:
- -Các lvalue thường là những biến có tên
- -Các rvalue thường là những biến ko có tên
- -Các đối tượng tạm được tạo ra trong quá trình tính toán biểu thức là rvaule
- -Khi 1 hàm trả về giá trị của 1 biến thì giá trị trả về đó là rvalue (vì chương
- trình phải tạo ra 1 đối tượng tạm để chứa giá trị của biến đó trả về)
- lvaule references
- -------------
- lvalue reference là những tham chiếu thông thường mà ta hay dùng, khi "rvalue
- references" ra đời và để phân biệt với rvalue references người ta còn gọi nó là "lvalue
- references". lvalue reference có thể dùng tham chiếu đến 1 lvalue, nhưng ko thể dùng để
- tham chiếu đến 1 rvalue.
- ```cpp
- int a=2;
- //biên dịch được vì lvalue reference tham chiếu đến lvalue
- int &b=a;
- //biên dịch lỗi vì c là lvalue reference nhưng 2 là 1 rvalue
- int &c=2;
- ```
- Trong c++ lại cho phép dùng const lvalue reference để tham chiếu đến rvalue.
- Khi dùng const lvalue reference tham chiếu đến rvalue thì rvalue đó chỉ bị hủy khi const
- lvalue reference đó bị hủy, chứ ko bị hủy ngay sau khi biểu thức kết thúc nữa.
- ```cpp
- //không báo lỗi vì dùng const lvalue reference để tham chiếu đế rvalue
- const int &c=2;
- ```
- rvalue references
- -------------
- Có loại tham chiếu nào dùng để tham chiếu đến rvalue ko?
- Nếu từ trước C++11 thì loại tham chiếu này ko tồn tại, nhưng từ C++11 đã có thêm 1 khái niệm mới
- "rvalue reference" - reference to rvalue. Kiểu dữ liệu rvalue reference có thể được
- khai báo bằng cách thêm dấu "&&". Ví dụ string&& là 1 "rvalue reference to string".
- Kí hiệu "&&" có thể dễ gây nhầm lẫn đây là một "reference to reference", nhưng đây
- là kí hiệu của rvalue reference, và trong C++ cũng ko có khái niệm "reference to reference".
- Dù tên gọi của "rvalue reference" có từ "tham chiếu", nhưng nó thường ko được dùng vào
- mục đích để tham chiếu đến 1 rvalue. Mà mục đích chính của nó là để giupsta nhận ra
- đâu là lvalue, đâu là rvalue. Vì chỉ có rvalue reference mới có thể tham chiếu đến rvalue,
- nên nếu ta có 2 hàm cùng tên và giá trị trả về, 1 hàm nhận đối số string& và 1
- hàm nhận đối số string&& thì:
- -Nếu giá trị truyền vào là 1 lvalue thì hàm có đối số là string& sẽ được gọi.
- -Nếu giá trị truyền vào là 1 rvalue thì hàm có đối số là string&& sẽ được gọi.
- Nói 1 cách ngắn gọn, rvalue là 1 loại tham chiếu mới mà nó chỉ có thể được dùng để
- tham chiếu tới rvalue. Và nhờ đó mà ta có thể định nghĩa được "move semantics"
- để giảm thiểu tối đa chi phí copy dữ liệu vô ích (copy dữ liệu từ đối tượng tạm).
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement