ตัวดำเนินการลูกศร ( ->) คำพ้องความหมายคืออะไร?
ตัวดำเนินการลูกศร ( ->) คำพ้องความหมายคืออะไร?
คำตอบ:
สองนิพจน์ต่อไปนี้เทียบเท่า:
a->b
(*a).b
(ขึ้นอยู่กับการโอเวอร์โหลดของตัวดำเนินการตามที่ Konrad กล่าวถึง แต่นั่นเป็นเรื่องผิดปกติ)
a[0].b (*a).bแต่มันจะไม่มีโครงสร้างที่เหมาะสม
a->b(*a).bโดยทั่วไปคำพ้องความหมายสำหรับ วงเล็บตรงนี้จำเป็นเนื่องจากความแข็งแรงในการผูกของตัวดำเนินการ*และ.: ใช้ *a.bไม่ได้เพราะ.ผูกแน่นกว่าและถูกดำเนินการก่อน จึงเทียบเท่ากับ*(a.b).
ระวังการใช้งานมากเกินไป: เนื่องจากทั้งสองอย่าง->และ*สามารถใช้งานได้มากเกินไปความหมายของมันอาจแตกต่างกันอย่างมาก
binding strengthคุณหมายถึงความสำคัญของตัวดำเนินการ? ถ้าไม่ใช่อะไรคือความแตกต่างระหว่างทั้งสอง?
ภาษา C ++ กำหนดตัวดำเนินการลูกศร ( ->) เป็นคำพ้องความหมายสำหรับการ.ยกเลิกการอ้างอิงตัวชี้จากนั้นใช้-operator บนที่อยู่นั้น
ตัวอย่างเช่น:
หากคุณมีวัตถุanObjectและตัวชี้aPointer:
SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;
เพื่อให้สามารถใช้วิธีการวัตถุอย่างใดอย่างหนึ่งที่คุณยกเลิกการอ้างอิงตัวชี้และเรียกใช้เมธอดบนที่อยู่นั้น:
(*aPointer).method();
ซึ่งสามารถเขียนได้ด้วยตัวดำเนินการลูกศร:
aPointer->method();
สาเหตุหลักของการมีอยู่ของตัวดำเนินการลูกศรคือมันทำให้การพิมพ์งานทั่วไปสั้นลงและยังง่ายต่อการลืมวงเล็บรอบ ๆ การอ้างอิงตัวชี้ หากคุณลืมวงเล็บตัวดำเนินการจะผูกแน่นกว่าแล้ว * -operator และทำให้ตัวอย่างของเราดำเนินการเป็น:
*(aPointer.method()); // Not our intention!
คำตอบอื่น ๆ บางส่วนได้กล่าวถึงทั้งสองอย่างว่าตัวดำเนินการ C ++ สามารถโอเวอร์โหลดได้และไม่ใช่เรื่องธรรมดา
new SomeClass()ส่งคืนตัวชี้ ( SomeClass *) ไม่ใช่SomeClassวัตถุ และคุณเริ่มต้นด้วยการประกาศanObjectและaPointerแต่คุณกำลังใช้ในpภายหลัง
ใน C ++ 0x ตัวดำเนินการจะได้รับความหมายที่สองซึ่งระบุประเภทการส่งคืนของฟังก์ชันหรือนิพจน์แลมบ์ดา
auto f() -> int; // "->" means "returns ..."
::เป็นตัวดำเนินการเหมือน.หรือ->และเรียกว่า "ตัวดำเนินการแก้ไขขอบเขต" ในมาตรฐาน
ส่วนใหญ่ฉันอ่านจากขวาไปซ้ายและเรียก "in"
foo->bar->baz = qux->croak
กลายเป็น:
"baz in bar in foo กลายเป็นเสียงดังใน qux"
-> ใช้เมื่อเข้าถึงข้อมูลที่คุณมีตัวชี้
ตัวอย่างเช่นคุณสามารถสร้าง ptr ตัวชี้ไปยังตัวแปรประเภท int intVar ดังนี้:
int* prt = &intVar;
จากนั้นคุณสามารถใช้ฟังก์ชันเช่น foo ได้โดยการยกเลิกการอ้างอิงตัวชี้นั้นเท่านั้น - เพื่อเรียกใช้ฟังก์ชันบนตัวแปรที่ตัวชี้ชี้ไปที่แทนที่จะใช้ค่าตัวเลขของตำแหน่งหน่วยความจำของตัวแปรนั้น:
(*ptr).foo();
หากไม่มีวงเล็บตรงนี้คอมไพเลอร์จะเข้าใจสิ่งนี้*(ptr.foo())เนื่องจากความสำคัญของตัวดำเนินการซึ่งไม่ใช่สิ่งที่เราต้องการ
นี่ก็เหมือนกับการพิมพ์
ptr->foo();
ในฐานะที่เป็น->dereferences ตัวชี้นั้นและเรียกใช้ฟังก์ชันfoo()บนตัวแปรที่ตัวชี้ชี้ให้เรา
ในทำนองเดียวกันเราสามารถใช้->เพื่อเข้าถึงหรือตั้งค่าสมาชิกของคลาส:
myClass* ptr = &myClassMember;
ptr->myClassVar = 2;
คุณสามารถใช้ -> เพื่อกำหนดฟังก์ชัน
auto fun() -> int
{
return 100;
}
มันไม่ใช่แลมด้า มันเป็นฟังก์ชั่นจริงๆ "->" ระบุประเภทการส่งคืนของฟังก์ชัน
->ผู้ประกอบการประเภท iterator บางอย่างเพื่อให้มี*.การใช้งาน ห้องสมุดหลายแห่งกำหนดไม่สอดคล้องกัน กลายเป็นเรื่องน่ารำคาญจริงๆเมื่อคุณทำงานกับเทมเพลตและไม่รู้ประเภทที่แม่นยำ