ตัวดำเนินการลูกศร ( ->
) คำพ้องความหมายคืออะไร?
ตัวดำเนินการลูกศร ( ->
) คำพ้องความหมายคืออะไร?
คำตอบ:
สองนิพจน์ต่อไปนี้เทียบเท่า:
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 บางอย่างเพื่อให้มี*.
การใช้งาน ห้องสมุดหลายแห่งกำหนดไม่สอดคล้องกัน กลายเป็นเรื่องน่ารำคาญจริงๆเมื่อคุณทำงานกับเทมเพลตและไม่รู้ประเภทที่แม่นยำ