ฉันคิดว่าข้อ จำกัด ที่คุณพิจารณาแล้วไม่เกี่ยวข้องกับซีแมนทิกส์ (ทำไมบางสิ่งควรเปลี่ยนหากการกำหนดค่าเริ่มต้นถูกกำหนดไว้ในไฟล์เดียวกัน?) แต่แทนที่จะเป็นรูปแบบการคอมไพล์ C ++ ซึ่งสำหรับเหตุผลของความเข้ากันได้แบบย้อนหลัง อาจซับซ้อนเกินไป (สนับสนุนรูปแบบการรวบรวมใหม่และแบบที่มีอยู่ในเวลาเดียวกัน) หรือจะไม่อนุญาตให้รวบรวมรหัสที่มีอยู่ (โดยการแนะนำแบบจำลองการรวบรวมใหม่
โมเดลการคอมไพล์ C ++ นั้นเกิดจากของ C ซึ่งคุณนำเข้าการประกาศไปยังไฟล์ต้นฉบับโดยการรวมไฟล์ (ส่วนหัว) ด้วยวิธีนี้คอมไพเลอร์จะเห็นไฟล์แหล่งใหญ่หนึ่งไฟล์ที่มีไฟล์ที่รวมทั้งหมดและไฟล์ทั้งหมดที่รวมจากไฟล์เหล่านั้นซ้ำ ๆ นี่เป็นข้อได้เปรียบที่ยิ่งใหญ่อย่างหนึ่งของ IMO คือทำให้คอมไพเลอร์ใช้งานง่ายขึ้น แน่นอนคุณสามารถเขียนอะไรก็ได้ในไฟล์ที่รวมอยู่นั่นคือทั้งการประกาศและคำจำกัดความ เป็นการดีที่จะใส่การประกาศในไฟล์ส่วนหัวและคำจำกัดความในไฟล์. c หรือ. cpp
ในทางกลับกันก็เป็นไปได้ที่จะมีรูปแบบการสะสมซึ่งคอมไพเลอร์รู้ดีหากมีการนำเข้าการประกาศของสัญลักษณ์ทั่วโลกที่มีการกำหนดไว้ในโมดูลอื่นหรือหากมีการรวบรวมความหมายของสัญลักษณ์ที่ทั่วโลกให้บริการโดย โมดูลปัจจุบัน ในกรณีหลังคอมไพเลอร์ต้องใส่สัญลักษณ์นี้ (เช่นตัวแปร) ในไฟล์วัตถุปัจจุบัน
ตัวอย่างเช่นในGNU Pascalคุณสามารถเขียนหน่วยa
ในไฟล์a.pas
ดังนี้:
unit a;
interface
var MyStaticVariable: Integer;
implementation
begin
MyStaticVariable := 0
end.
โดยที่ตัวแปรโกลบอลถูกประกาศและกำหนดค่าเริ่มต้นในไฟล์ต้นฉบับเดียวกัน
จากนั้นคุณสามารถมีหน่วยต่าง ๆ ที่นำเข้าและใช้ตัวแปรโกลบอล
MyStaticVariable
เช่นหน่วย b ( b.pas
):
unit b;
interface
uses a;
procedure PrintB;
implementation
procedure PrintB;
begin
Inc(MyStaticVariable);
WriteLn(MyStaticVariable)
end;
end.
และหน่วย c ( c.pas
):
unit c;
interface
uses a;
procedure PrintC;
implementation
procedure PrintC;
begin
Inc(MyStaticVariable);
WriteLn(MyStaticVariable)
end;
end.
ในที่สุดคุณสามารถใช้หน่วย b และ c ในโปรแกรมหลักm.pas
:
program M;
uses b, c;
begin
PrintB;
PrintC;
PrintB
end.
คุณสามารถรวบรวมไฟล์เหล่านี้แยกกัน:
$ gpc -c a.pas
$ gpc -c b.pas
$ gpc -c c.pas
$ gpc -c m.pas
แล้วสร้างไฟล์ปฏิบัติการด้วย:
$ gpc -o m m.o a.o b.o c.o
และเรียกใช้:
$ ./m
1
2
3
เคล็ดลับที่นี่คือเมื่อคอมไพเลอร์เห็นdirective ใช้ในโมดูลโปรแกรม (เช่นใช้ใน b.pas) มันไม่รวมไฟล์. pas ที่สอดคล้องกัน แต่มองหาไฟล์. gpi เช่นสำหรับรวบรวมไว้ล่วงหน้า ไฟล์อินเตอร์เฟส (ดูเอกสารประกอบ ) .gpi
ไฟล์เหล่านี้ถูกสร้างโดยคอมไพเลอร์พร้อมกับ.o
ไฟล์เมื่อแต่ละโมดูลถูกคอมไพล์ ดังนั้นสัญลักษณ์ทั่วโลกถูกกำหนดให้เพียงครั้งเดียวในไฟล์วัตถุMyStaticVariable
a.o
Java ทำงานในลักษณะที่คล้ายกันเมื่อนำเข้าแล้วคอมไพเลอร์ชั้นลงไปในชั้น B ก็มีลักษณะที่ไฟล์ระดับสำหรับ A A.java
และไม่จำเป็นต้องใช้ไฟล์ ดังนั้นคำจำกัดความและการกำหนดค่าเริ่มต้นสำหรับคลาส A สามารถใส่ในไฟล์ต้นฉบับไฟล์เดียว
กลับไปที่ C ++ สาเหตุที่ใน C ++ คุณต้องกำหนดสมาชิกสแตติกข้อมูลในไฟล์แยกต่างหากเกี่ยวข้องกับโมเดลการรวบรวม C ++ มากกว่าข้อ จำกัด ที่ linker หรือเครื่องมืออื่น ๆ ที่ใช้โดยคอมไพเลอร์ ใน C ++ การนำเข้าสัญลักษณ์บางอย่างหมายถึงการสร้างการประกาศของพวกเขาเป็นส่วนหนึ่งของหน่วยการรวบรวมปัจจุบัน นี่เป็นสิ่งสำคัญอย่างยิ่งเนื่องจากวิธีการรวบรวมแม่แบบ แต่นี่ก็หมายความว่าคุณไม่สามารถ / ไม่ควรกำหนดสัญลักษณ์ทั่วโลก (ฟังก์ชั่นตัวแปรวิธีการสมาชิกข้อมูลคงที่) ในไฟล์ที่รวมมิฉะนั้นสัญลักษณ์เหล่านี้อาจถูกกำหนดทวีคูณในไฟล์วัตถุที่รวบรวม