ความแตกต่างระหว่าง Lvalue กับ Rvalue
วิเคราะห์หมวดหมู่ของค่า ได้แก่ lvalue, prvalue และ xvalue
ความแตกต่างระหว่าง Lvalue กับ Rvalue เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
สองโลก: Lvalue และ Rvalue
ทุกนิพจน์ใน C++ เป็นอย่างใดอย่างหนึ่งระหว่าง lvalue (สิ่งที่มีชื่อและแอดเดรส) หรือ rvalue (ค่าชั่วคราวที่ไม่มีชื่อ)
Lvalue
lvalue อ้างถึงออบเจ็กต์ที่คงอยู่ คุณสามารถขอแอดเดรสของมันด้วย &
int x = 42; // x is an lvalue
int* p = &x; // taking the address of an lvalue
int& r = x; // r is an lvalue referenceRvalue
rvalue คือค่าชั่วคราว เช่น ค่าลิเทอรัล ค่าที่ฟังก์ชันส่งคืน และนิพจน์อย่าง a + b ไม่สามารถขอแอดเดรสของมันได้
int a = 5, b = 3;
int c = a + b; // (a + b) is an rvalue
// int* p = &(a + b); // ERROR: cannot take address of an rvalueเหตุใดความแตกต่างนี้จึงสำคัญ
rvalue กำลังจะถูกทำลาย เราจึงสามารถ ขโมย ทรัพยากรของมันแทนการคัดลอกได้อย่างปลอดภัย ซึ่งเป็นพื้นฐานของซีแมนติกส์การย้าย
สามหมวดหมู่ตั้งแต่ C++11
C++ สมัยใหม่ปรับปรุงแบบจำลองนี้ให้ละเอียดขึ้น:
- lvalue — มีชื่อและเอกลักษณ์
- prvalue (rvalue แท้) — ค่าชั่วคราวอย่างแท้จริง (ค่าลิเทอรัล หรือค่าที่ส่งคืนตามค่า)
- xvalue (ค่าที่กำลังหมดอายุ) — กำลังจะถูกทำลาย (ผลลัพธ์ของ
std::move)
การอ้างอิง lvalue และ rvalue
การอ้างอิง lvalue ใช้ & ส่วน การอ้างอิง rvalue ใช้ &&
int x = 10;
int& lr = x; // lvalue reference
int&& rr = 42; // rvalue reference, binds to literalกฎการผูกการอ้างอิง
ความเข้ากันได้ของชนิด:
- การอ้างอิง lvalue (
T&) ผูกกับ lvalue - การอ้างอิง lvalue แบบ const (
const T&) ผูกได้ทั้งสองแบบ - การอ้างอิง rvalue (
T&&) ผูกได้เฉพาะกับ rvalue (และ xvalue)
ตรวจสอบด้วย decltype
คุณสามารถถามคอมไพเลอร์ได้ว่านิพจน์เป็นหมวดหมู่ใด โดยใช้ decltype กับนิพจน์นั้น
int x = 10;
static_assert(std::is_lvalue_reference<decltype((x))>::value);
// the extra parentheses make decltype yield the lvalue refเหตุใด C++11 จึงเพิ่มการอ้างอิง rvalue
เพื่อรองรับ ซีแมนติกส์การย้าย ตัวสร้างที่รับ T&& สามารถรับช่วงข้อมูลภายในของค่าชั่วคราวมาเป็นเจ้าของได้ จึงหลีกเลี่ยงการคัดลอกแบบลึก
ข้อผิดพลาดที่พบบ่อย: การอ้างอิง rvalue ที่มีชื่อเป็น lvalue
เมื่อตัวแปรการอ้างอิง rvalue ถูกประกาศแล้ว ตัวแปรนั้นจะมีชื่อ ทำให้เป็น lvalue หากต้องการส่งต่อในฐานะ rvalue ให้ใช้ std::move
void f(std::string&& s) {
// s here is an lvalue!
process(std::move(s)); // now it is an rvalue again
}ภาพรวมการส่งต่อตรงแบบสมบูรณ์
แม่แบบที่รับ T&& จะอนุมานได้ว่าเป็นการอ้างอิง lvalue หรือ rvalue เมื่อใช้ร่วมกับ std::forward ก็สามารถรักษาหมวดหมู่ของค่าไว้ได้ ซึ่งจะอธิบายโดยละเอียดในภายหลัง
ตรวจสอบความเข้าใจ
นิพจน์ใดต่อไปนี้เป็น rvalue
สรุปทบทวน
lvalue มีชื่อและแอดเดรส ส่วน rvalue เป็นค่าชั่วคราว T& ผูกกับ lvalue และ T&& ผูกกับ rvalue ความแตกต่างนี้ทำให้เกิดซีแมนติกส์การย้าย ซึ่งช่วยหลีกเลี่ยงการคัดลอกค่าชั่วคราวโดยไม่จำเป็น
คำถามที่พบบ่อย
บทเรียน “ความแตกต่างระหว่าง Lvalue กับ Rvalue” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ความแตกต่างระหว่าง Lvalue กับ Rvalue” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ความแตกต่างระหว่าง Lvalue กับ Rvalue”
วิเคราะห์หมวดหมู่ของค่า ได้แก่ lvalue, prvalue และ xvalue คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ความแตกต่างระหว่าง Lvalue กับ Rvalue” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ความแตกต่างระหว่าง Lvalue กับ Rvalue
- รีเฟอเรนซ์ Rvalue และไวยากรณ์ &&
- std::move และ std::forward
- คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย