มีความแตกต่างบางอย่างในการเรียกประชุมใน C ++ และ Java ใน C ++ มีเทคนิคการพูดเพียงสองอนุสัญญา: pass-by-value และ pass-by-reference โดยมีวรรณกรรมบางอย่างรวมถึงระเบียบการส่งต่อโดยตัวชี้ที่สาม (นั่นคือการส่งต่อค่าของประเภทตัวชี้) นอกเหนือจากนั้นคุณสามารถเพิ่ม const-ness ให้กับชนิดของอาร์กิวเมนต์เพื่อเพิ่มความหมาย
ผ่านการอ้างอิง
การส่งต่อโดยการอ้างอิงหมายถึงฟังก์ชั่นจะได้รับอินสแตนซ์วัตถุของคุณในเชิงแนวคิดไม่ใช่สำเนา การอ้างอิงเป็นแนวคิดนามแฝงของวัตถุที่ใช้ในบริบทการโทรและไม่สามารถเป็นค่าว่างได้ การดำเนินการทั้งหมดที่ดำเนินการภายในฟังก์ชั่นใช้กับวัตถุที่อยู่นอกฟังก์ชั่น การประชุมนี้ไม่สามารถใช้ได้ใน Java หรือ C
ส่งผ่านค่า (และผ่านตัวชี้)
คอมไพเลอร์จะสร้างสำเนาของวัตถุในบริบทการโทรและใช้สำเนานั้นภายในฟังก์ชั่น การดำเนินการทั้งหมดที่ดำเนินการภายในฟังก์ชั่นจะทำเพื่อคัดลอกไม่ใช่องค์ประกอบภายนอก นี่คือการประชุมสำหรับประเภทดั้งเดิมใน Java
รุ่นพิเศษกำลังส่งตัวชี้ (ที่อยู่ของวัตถุ) ไปยังฟังก์ชัน ฟังก์ชั่นได้รับตัวชี้และการดำเนินการใด ๆ และทั้งหมดที่ใช้กับตัวชี้จะถูกนำไปใช้กับสำเนา (ตัวชี้) ในทางกลับกันการดำเนินการที่ใช้กับตัวชี้การลงทะเบียนจะใช้กับอินสแตนซ์วัตถุที่ตำแหน่งหน่วยความจำนั้น สามารถมีผลข้างเคียง ผลของการใช้ pass-by-value ของตัวชี้ไปยังวัตถุจะทำให้ฟังก์ชันภายในสามารถแก้ไขค่าภายนอกเช่นเดียวกับ pass-by-reference และจะอนุญาตให้มีค่าที่เป็นตัวเลือก (ผ่านตัวชี้ null)
นี่คือการประชุมที่ใช้ใน C เมื่อฟังก์ชั่นต้องการแก้ไขตัวแปรภายนอกและการประชุมที่ใช้ใน Java ที่มีประเภทการอ้างอิง: การอ้างอิงจะถูกคัดลอก แต่วัตถุที่อ้างถึงเหมือนกัน: การเปลี่ยนแปลงการอ้างอิง / ตัวชี้จะมองไม่เห็นภายนอก ฟังก์ชั่น แต่การเปลี่ยนแปลงหน่วยความจำแหลมเป็น
การเพิ่ม const ในสมการ
ใน C ++ คุณสามารถกำหนดค่าคงที่ให้กับวัตถุได้เมื่อกำหนดตัวแปรพอยน์เตอร์และการอ้างอิงในระดับต่าง ๆ คุณสามารถประกาศตัวแปรให้เป็นค่าคงที่คุณสามารถประกาศการอ้างอิงไปยังอินสแตนซ์คงที่และคุณสามารถกำหนดพอยน์เตอร์ทั้งหมดไปยังวัตถุคงที่พอยน์เตอร์คงที่ไปยังวัตถุที่ไม่แน่นอนและพอยน์เตอร์คงที่ ตรงกันข้ามใน Java คุณสามารถกำหนดหนึ่งระดับคงที่ (คำหลักสุดท้าย): ของตัวแปร (อินสแตนซ์สำหรับประเภทดั้งเดิมการอ้างอิงสำหรับประเภทการอ้างอิง) แต่คุณไม่สามารถกำหนดการอ้างอิงไปยังองค์ประกอบที่ไม่เปลี่ยนรูป ไม่เปลี่ยนรูป)
สิ่งนี้ถูกใช้อย่างกว้างขวางในการเรียกการประชุม C ++ เมื่อวัตถุมีขนาดเล็กคุณสามารถส่งผ่านวัตถุตามค่า คอมไพเลอร์จะสร้างสำเนา แต่สำเนานั้นไม่ใช่การดำเนินการที่มีราคาแพง สำหรับประเภทอื่น ๆ หากฟังก์ชั่นจะไม่เปลี่ยนวัตถุคุณสามารถส่งการอ้างอิงไปยังอินสแตนซ์คงที่ (มักจะเรียกว่าการอ้างอิงคงที่) ของประเภท สิ่งนี้จะไม่คัดลอกวัตถุ แต่ส่งผ่านไปยังฟังก์ชัน แต่ในเวลาเดียวกันคอมไพเลอร์จะรับประกันว่าวัตถุจะไม่เปลี่ยนแปลงภายในฟังก์ชั่น
กฎของหัวแม่มือ
นี่เป็นกฎพื้นฐานบางประการที่จะต้องปฏิบัติตาม:
- ชอบ pass-by-value สำหรับประเภทดั้งเดิม
- ชอบ Pass-by-Reference พร้อมการอ้างอิงค่าคงที่สำหรับประเภทอื่น ๆ
- หากฟังก์ชันจำเป็นต้องแก้ไขอาร์กิวเมนต์ให้ใช้การอ้างอิงแบบอ้างอิงถึงกัน
- หากอาร์กิวเมนต์เป็นทางเลือกให้ใช้การบายพาสตัวชี้ (เป็นค่าคงที่หากไม่ใส่ค่าทางเลือก)
มีการเบี่ยงเบนเล็กน้อยจากกฎเหล่านี้ประการแรกคือการจัดการความเป็นเจ้าของวัตถุ เมื่อวัตถุได้รับการจัดสรรแบบไดนามิกด้วยใหม่วัตถุนั้นจะต้องถูกจัดสรรคืนด้วยการลบ (หรือ [] รุ่นดังกล่าว) วัตถุหรือฟังก์ชั่นที่รับผิดชอบการทำลายของวัตถุนั้นถือเป็นเจ้าของทรัพยากร เมื่อวัตถุที่จัดสรรแบบไดนามิกถูกสร้างขึ้นในชิ้นส่วนของรหัส แต่ความเป็นเจ้าของจะถูกโอนไปยังองค์ประกอบที่แตกต่างกันมันมักจะทำด้วยความหมายแบบบายพาสตัวชี้หรือถ้าเป็นไปได้ด้วยตัวชี้สมาร์ท
ข้อความด้านข้าง
สิ่งสำคัญคือต้องยืนยันในความสำคัญของความแตกต่างระหว่างการอ้างอิง C ++ และ Java ในการอ้างอิง C ++ เป็นแนวคิดของอินสแตนซ์ของวัตถุไม่ใช่ accessor ตัวอย่างที่ง่ายที่สุดคือการนำฟังก์ชัน swap ไปใช้:
// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
Type tmp = a;
a = b;
b = tmp;
}
int main() {
Type a, b;
Type old_a = a, old_b = b;
swap( a, b );
assert( a == old_b );
assert( b == old_a );
}
ฟังก์ชั่นการแลกเปลี่ยนด้านบนเปลี่ยนการขัดแย้งทั้งสองผ่านการใช้การอ้างอิง รหัสที่ใกล้เคียงที่สุดใน Java:
public class C {
// ...
public static void swap( C a, C b ) {
C tmp = a;
a = b;
b = tmp;
}
public static void main( String args[] ) {
C a = new C();
C b = new C();
C old_a = a;
C old_b = b;
swap( a, b );
// a and b remain unchanged a==old_a, and b==old_b
}
}
รหัส Java เวอร์ชันจะแก้ไขสำเนาของการอ้างอิงภายใน แต่จะไม่แก้ไขวัตถุจริงภายนอก การอ้างอิง Java เป็นพอยน์เตอร์ C โดยไม่มีตัวชี้ทางคณิตศาสตร์ที่ส่งผ่านค่าไปยังฟังก์ชั่น