Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.02 KB | None | 0 0
  1. #Temporaray object
  2. ==================
  3. Đố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
  4. ```cpp
  5. int a=4+(3*b);
  6. ```
  7. Ở 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)
  8. Phân tích rõ hơn việc sd 2 đối tượng tạm trong code trên:
  9. ```cpp
  10. int temp1=3*b;
  11. int temp2=4+temp1;
  12. int a=temp2;
  13. ```
  14. 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ử
  15. dụng temporary object, còn đoạn thứ hai ta sử dụng named object để chứa giá trị tạm.
  16.  
  17. Ta thường sẽ gặp các loại đối tượng sau:
  18.  
  19. -Giá trị trung gian trong quá trình tính toán biểu thức. vd int a=4+(3*b);
  20.  
  21. -Biến trả về từ hàm.
  22. ```cpp
  23. std::vector<int> sortedArray=createSortedArray(intputedArray);
  24. ```
  25. -Biến được khởi tạo nhưng ko đặt tên.
  26. ```cpp
  27. if(string("dieuninh")==string("xinhgai"));
  28. ```
  29. 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
  30. nên 2 đối tượng này là 2 đối tượng tạm.
  31.  
  32. =>Đố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,
  33. 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
  34. 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í
  35. cho việc copy trạng thái (dữ liệu) của đối tượng tạm.
  36.  
  37.  
  38. #lvalue, rvalue và lvalue reference
  39. =============
  40. lvaule và rvalue
  41. -------------
  42. ```cpp
  43. C++11’s most pervasive feature is probably move semantics, and the foundation of
  44. move semantics is distinguishing expressions that are rvaluesfrom those that are lval‐
  45. ues. That’s because rvalues indicate objects eligible for move operations, while lvalues
  46. generally don’t. In concept (though not always in practice), rvalues correspond to
  47. temporary objects returned from functions, while lvalues correspond to objects you
  48. can refer to, either by name or by following a pointer or lvalue reference.
  49. <trích từ ebook Effective Morden C++ của Scott Meyers>
  50. ```
  51.  
  52. Đọc giải thích ở sách t.anh có vẻ khó hiểu.
  53. 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ó
  54. 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ó).
  55. 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
  56. báo lỗi "lvalue required as left operand of assignment" thì chắc chắn giá trị đó là rvalue.
  57. Vậy ta có thể hiểu lvalue là giá trị có thể gán được, còn rvalue là giá trị ko thể
  58. 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ử '&'
  59. nhưng ko thể lấy địa chỉ của rvalue.
  60. ```cpp
  61. //dream là 1 lvalue do phép gán bên dưới thành công;
  62. string dream="I can make it";
  63. // doNothing*beRich là 1 rvalue vì compiler sẽ báo lỗi dòng này
  64. int doNothing=1, beRich=2;
  65. (doNothing*beRich)=8;
  66. ```
  67. 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à
  68. 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
  69. 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
  70. khi ra khỏi phạm vi định nghĩa của nó.
  71. ```cpp
  72. int main()
  73. {
  74. int b=2;
  75. //giả sử có 2 biến tạm temp1=3*b và temp2=4+temp1 được tạo ra
  76. //hủy temp1 và temp2 vì đã kết thúc biểu thức a=4+(3*b) chứa nó
  77. int a=4+(3*b);
  78. a=3;
  79. //hủy a,b
  80. }
  81. ```
  82. Khái quát hơn, ta có:
  83.  
  84. -Các lvalue thường là những biến có tên
  85.  
  86. -Các rvalue thường là những biến ko có tên
  87.  
  88. -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
  89.  
  90. -Khi 1 hàm trả về giá trị của 1 biến thì giá trị trả về đó là rvalue (vì chương
  91. trình phải tạo ra 1 đối tượng tạm để chứa giá trị của biến đó trả về)
  92.  
  93. lvaule references
  94. -------------
  95. lvalue reference là những tham chiếu thông thường mà ta hay dùng, khi "rvalue
  96. references" ra đời và để phân biệt với rvalue references người ta còn gọi nó là "lvalue
  97. references". lvalue reference có thể dùng tham chiếu đến 1 lvalue, nhưng ko thể dùng để
  98. tham chiếu đến 1 rvalue.
  99. ```cpp
  100. int a=2;
  101. //biên dịch được vì lvalue reference tham chiếu đến lvalue
  102. int &b=a;
  103. //biên dịch lỗi vì c là lvalue reference nhưng 2 là 1 rvalue
  104. int &c=2;
  105. ```
  106. Trong c++ lại cho phép dùng const lvalue reference để tham chiếu đến rvalue.
  107. Khi dùng const lvalue reference tham chiếu đến rvalue thì rvalue đó chỉ bị hủy khi const
  108. lvalue reference đó bị hủy, chứ ko bị hủy ngay sau khi biểu thức kết thúc nữa.
  109. ```cpp
  110. //không báo lỗi vì dùng const lvalue reference để tham chiếu đế rvalue
  111. const int &c=2;
  112. ```
  113.  
  114. rvalue references
  115. -------------
  116. Có loại tham chiếu nào dùng để tham chiếu đến rvalue ko?
  117. 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
  118. "rvalue reference" - reference to rvalue. Kiểu dữ liệu rvalue reference có thể được
  119. khai báo bằng cách thêm dấu "&&". Ví dụ string&& là 1 "rvalue reference to string".
  120.  
  121. Kí hiệu "&&" có thể dễ gây nhầm lẫn đây là một "reference to reference", nhưng đây
  122. là kí hiệu của rvalue reference, và trong C++ cũng ko có khái niệm "reference to reference".
  123.  
  124. 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
  125. mục đích để tham chiếu đến 1 rvalue. Mà mục đích chính của nó là để giupsta nhận ra
  126. đâu là lvalue, đâu là rvalue. Vì chỉ có rvalue reference mới có thể tham chiếu đến rvalue,
  127. 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
  128. hàm nhận đối số string&& thì:
  129.  
  130. -Nếu giá trị truyền vào là 1 lvalue thì hàm có đối số là string& sẽ được gọi.
  131.  
  132. -Nếu giá trị truyền vào là 1 rvalue thì hàm có đối số là string&& sẽ được gọi.
  133.  
  134. 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 để
  135. tham chiếu tới rvalue. Và nhờ đó mà ta có thể định nghĩa được "move semantics"
  136. để 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