Nội dung
Nếu trong C, định nghĩa lvalue và rvalue có phần đơn giản, bất cứ cái gì, miễn là bên trái của toán tử gán là lvalue và bên phải của phép gàn là rvalue. Nhưng trong C++, định nghĩa này đã thay đổi và trở nên thú vị hơn. Mỗi biểu thức trong C++ là lvalue hoặc là rvalue. Ta sẽ giải thích từng cái một nào!
lvalue là gì?
lvalue là bất cứ thứ gì mà địa chỉ của nó có thể truy cập được. Điều đó có nghĩa là chúng ta có thể lấy được địa chỉ của lvalue bằng cách sử dụng toán tử &. Hãy xem xét một số ví dụ sau,
Ví dụ 1:
int x = 1;
int * ptr = &x;
Trong biểu thức trên, x là một lvalue vì ta có thể truy cập địa chỉ của x.
Ví dụ 2:
int z = x + 1;
int * ptr2 = &z;
Int * ptr3 = &(x+1); // Compile Error
Trong ví dụ trên, z cũng là lvalue vì ta có truy cập được địa chỉ của nó. Trong khi đó, (x+1) không phải là một lvalue. Đoạn chương trình trên bị lỗi khi biên dịch vì chúng ta đang cố truy cập địa chỉ của (x+1) và (x+1) thì không tồn tại một địa chỉ sau khi biểu thức này được tính toán. Vì vậy, chúng ta thể lấy được địa chỉ của nó. Vậy (x+1) ở đây được gọi là gì?
Như vậy, lvalue là một cái gì đó có địa chỉ có thể truy cập bằng cách sử dụng toán tử &. Nhưng trong trường hợp này, ta không thể truy cập địa chỉ của (x + 1). Vì vậy, (x + 1) là một cái gì đó không phải là lvalue và đó chính xác là rvalue. (x + 1) ở đây là rvalue.
rvalue là gì?
rvalue là bất cứ thứ gì không phải là lvalue. Điều đó có nghĩa là chúng ta không thể lấy địa chỉ của rvalue và nó cũng không tồn tại vượt ra khỏi biểu thức đơn. Hãy xem một số ví dụ sau,
Ví dụ 3:
int x = 1;
int * ptr = &(1); // Compile Error
Trong ví dụ trên, ta không thể lấy địa chỉ của 1. Vì vậy, 1 không phải là lvalue mà là rvalue.
Ví dụ 4:
int a = x+1;
int * ptr3 = &(x+1); // Compile Error
Đồng đạng như trên, (x+1) cũng không phải là lvalue mà là rvalue.
Hãy xem một số ví dụ bên dưới và check xem đâu là lvalue, đâu là rvalue.
int b = (a + 2); // b is lvalue & (a+2) is rvalue
int c = (a + b) ; // c is lvalue & (a+b) is rvalue
int * ptr = &a; // Possible to take address of lvalue
//int * ptr3 = &(a + 1); // Compile Error. Can not take address of rvalue
Bây giờ, hãy tạo ra một hàm và trả về giá trị kiểu integer.
int getData()
{
int data = 0;
return data;
}
Ở đây, giá trị được trả về bởi getData() là tạm thời, nó sẽ không tồn tại ngoài phạm vi biểu thức nơi nó được gọi. Do đó, nó sẽ được sao chép.Chúng ta không thể lấy địa chỉ của giá trị tạm thời được trả về bởi getData() tức là,
int * ptr = &getData(); // Compile error - Cannot take address of rvalue
Như vây, getData() là một là rvalue và chúng ta không thể lấy được địa chỉ của rvalue.
Để lại một bình luận