เนื่องจากวิธีการทำงานของ Objective-C const
ทำให้การบังคับใช้และเริ่มต้นเป็นสัญกรณ์สำหรับโปรแกรมเมอร์ พิจารณาโปรแกรมนี้:
int f(const int x) {
return ++x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int x = 3;
NSLog(@"%d", f(x));
}
return 0;
}
ที่จริงแล้วจะไม่รวบรวมที่นี่ (ฉันใช้เสียงดังกราว): คอมไพเลอร์สามารถตรวจพบความพยายามในการแก้ไขประเภท C ดั้งเดิมและปล่อยข้อผิดพลาด แต่ตอนนี้เปรียบเทียบกับโปรแกรมนี้:
NSMutableString *f2(const NSMutableString * const x) {
[x appendString: @" world!"];
return x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
NSMutableString *x = [@"Hello" mutableCopy];
NSLog(@"%@", f2(x));
}
return 0;
}
แม้ว่าฟังก์ชั่นจะถูกส่งผ่านตัวชี้ค่าคงที่ไปยังวัตถุคงที่ แต่ก็ยังสามารถกลายพันธุ์วัตถุได้
ในการเขียนโปรแกรมเชิงวัตถุวิธีที่ดีที่สุดในการบังคับใช้ลักษณะคงที่ของวัตถุคือทำให้วัตถุนั้นไม่เปลี่ยนรูปนั่นคือไม่มีวิธีการใดที่สามารถเปลี่ยนสถานะของวัตถุนั้นได้ ลองนึกภาพว่าฟังก์ชั่นด้านบนรับการNSString
โต้เถียงแทนNSMutableString
และฉันจะผ่านตัวอักษร@"Hello"
แทนที่จะเป็นสำเนาที่ไม่แน่นอน ขณะนี้มีเหตุผลพูดไม่มีโอกาสที่จะกลายพันธุ์วัตถุที่ส่งผ่าน [*] Objective-C ไม่มีวิธีการบังคับใช้ที่แตกต่างconst
หรือfinal
อ้างอิงวัตถุในภาษา OO อื่น ๆ
สำหรับการเปรียบเทียบconst
ทำงานแตกต่างกันอย่างสิ้นเชิงใน C ++ ถ้าฉันได้รับการconst
อ้างอิงถึงวัตถุ C ++ ฉันได้รับอนุญาตให้เรียกconst
ฟังก์ชันสมาชิกบนวัตถุนั้นเท่านั้น ฟังก์ชั่นเหล่านี้รักษาความconst
-ness ของวัตถุโดยไม่ทำการเปลี่ยนแปลงใด ๆ หรือโดยการปรับเปลี่ยนตัวแปรสมาชิกที่ได้รับการทำเครื่องหมายmutable
โดยนักออกแบบชั้นอย่างชัดเจน ลองจินตนาการว่าฉันมีบางประเภทMutableString
ใน C ++ ที่เทียบเท่ากับNSMutableString
ใน Objective-C ตัวอย่างที่ได้กล่าวมาข้างต้นมีลักษณะคล้าย:
MutableString& f3(const MutableString& x) {
x.appendString(" world!");
return x;
}
นี้แน่นอนจะไม่รวบรวม: นอกเหนือจากการappendString()
ไม่เป็นconst
การดำเนินงานฟังก์ชั่นเอาคัดเลือกจากการอ้างอิงชนิดที่ต้องใช้const
const_cast
[*] ฉันคาดหวังว่าจะมีวิธีการทำบางอย่างที่ขัดแย้งกัน แต่ตอนนี้เราเข้าสู่อาณาจักรของโปรแกรมเมอร์คนหนึ่งที่พยายามก่อวินาศกรรมอีกครั้งโดยการทำสิ่งที่ "ฉลาด"