ขอบเขตใน C++

Scope C



เอนทิตีใน C++ มีชื่อซึ่งสามารถประกาศและ/หรือกำหนดได้ การประกาศเป็นคำจำกัดความ แต่คำจำกัดความไม่จำเป็นต้องเป็นการประกาศ คำนิยามจัดสรรหน่วยความจำสำหรับเอนทิตีที่มีชื่อ แต่การประกาศอาจหรือไม่อาจจัดสรรหน่วยความจำสำหรับเอนทิตีที่มีชื่อ ภูมิภาคประกาศเป็นส่วนที่ใหญ่ที่สุดของโปรแกรมที่ชื่อของเอนทิตี (ตัวแปร) ถูกต้อง ขอบเขตนั้นเรียกว่าขอบเขตหรือขอบเขตที่มีศักยภาพ บทความนี้อธิบายการกำหนดขอบเขตใน C++ นอกจากนี้ จำเป็นต้องมีความรู้พื้นฐานใน C++ เพื่อทำความเข้าใจบทความนี้

เนื้อหาบทความ

เขตประกาศและขอบเขต

ภูมิภาคประกาศเป็นส่วนที่ใหญ่ที่สุดของข้อความโปรแกรมซึ่งชื่อของเอนทิตีถูกต้อง เป็นภูมิภาคที่สามารถใช้ชื่อที่ไม่มีเงื่อนไข (เห็น) เพื่ออ้างถึงเอนทิตีเดียวกัน พิจารณาโปรแกรมสั้น ๆ ต่อไปนี้:







#รวม
โดยใช้ เนมสเปซชั่วโมง;

โมฆะfn()
{
intที่ไหน= 3;
ถ้า (1==1)
{
ค่าใช้จ่าย<<ที่ไหน<<'NS';
}
}

intหลัก()
{
fn();
กลับ 0;
}

ฟังก์ชัน fn() มีสองบล็อก: บล็อกภายในสำหรับเงื่อนไข if และบล็อกภายนอกสำหรับเนื้อหาของฟังก์ชัน ตัวระบุ var ถูกนำมาใช้และมองเห็นได้ในบล็อกภายนอก มันยังเห็นได้ในบล็อกชั้นในด้วยคำสั่งศาล บล็อกด้านนอกและด้านในเป็นทั้งขอบเขตของชื่อ var



อย่างไรก็ตาม ชื่อ var ยังคงสามารถใช้เพื่อประกาศเอนทิตีอื่นได้ เช่น ลอยในบล็อกภายใน รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:



#รวม
โดยใช้ เนมสเปซชั่วโมง;

โมฆะfn()
{
intที่ไหน= 3;
ถ้า (1==1)
{
ลอยที่ไหน= 7.5;
ค่าใช้จ่าย<<ที่ไหน<<'NS';
}
}

intหลัก()
{
fn();
กลับ 0;
}

เอาต์พุตคือ 7.5 ในกรณีนี้ ชื่อ var ไม่สามารถใช้ในบล็อกชั้นในเพื่ออ้างถึงจำนวนเต็มของค่า 3 ได้อีกต่อไป ซึ่งได้รับการแนะนำ (ประกาศ) ในบล็อกภายนอก บล็อคภายในดังกล่าวเรียกว่าขอบเขตที่เป็นไปได้สำหรับเอนทิตีที่ประกาศในบล็อกภายนอก





หมายเหตุ: เอนทิตีประเภทเดียวกัน เช่น บล็อกภายนอก ยังคงสามารถประกาศในบล็อกภายในได้ อย่างไรก็ตาม ในกรณีนี้ สิ่งที่ถูกต้องในบล็อคชั้นในคือการประกาศใหม่และความหมายของมัน ในขณะที่การประกาศแบบเก่าและความหมายภายนอกของบล็อคชั้นในยังคงใช้ได้ในบล็อคภายนอก

การประกาศชื่อเดียวกันในบล็อคภายในจะแทนที่การประกาศชื่อเดียวกันภายนอกบล็อคภายในนั้น บล็อคด้านในสามารถซ้อนบล็อคด้านในอื่นๆ ได้



ขอบเขตทั่วโลก

เมื่อโปรแกรมเมอร์เพิ่งเริ่มพิมพ์ไฟล์ นั่นคือขอบเขตสากล โปรแกรมสั้น ๆ ต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

ลอยที่ไหน= 9.4;

intหลัก()
{
ค่าใช้จ่าย <<ที่ไหน<<'NS';
ค่าใช้จ่าย <<::ที่ไหน<<'NS';

กลับ 0;
}

ผลลัพธ์คือ:
9.4
9.4

ในกรณีนี้ ขอบเขตหรือขอบเขตการประกาศสำหรับ var จะเริ่มต้นจากจุดประกาศสำหรับ var ไปจนถึงด้านล่างสุดของไฟล์ (หน่วยการแปล)

บล็อกของฟังก์ชัน main() เป็นขอบเขตที่แตกต่างกัน เป็นขอบเขตซ้อนสำหรับขอบเขตส่วนกลาง ในการเข้าถึงเอนทิตีของขอบเขตส่วนกลาง จากขอบเขตอื่น ตัวระบุจะถูกใช้โดยตรงหรือนำหน้าด้วยตัวดำเนินการแก้ไขขอบเขต ::

หมายเหตุ: เอนทิตี main() ได้รับการประกาศในขอบเขตส่วนกลางด้วย

บล็อกขอบเขต

คำสั่ง if, while, do, for, หรือ switch แต่ละคำสั่งสามารถกำหนดบล็อกได้ คำสั่งดังกล่าวเป็นคำสั่งผสม ชื่อของตัวแปรที่ประกาศในบล็อกมีขอบเขตของบล็อก ขอบเขตของมันเริ่มต้นที่จุดประกาศและสิ้นสุดที่จุดสิ้นสุดของบล็อก โปรแกรมสั้น ๆ ต่อไปนี้แสดงสิ่งนี้สำหรับตัวแปร ident:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

intหลัก()
{
ถ้า (1==1)
{
/*ข้อความบางส่วน*/
intตัวตน= 5;
ค่าใช้จ่าย<<ตัวตน<<'NS';
/*ข้อความบางส่วน*/
}
กลับ 0;
}

ตัวแปร เช่น ident ที่ประกาศที่ขอบเขตบล็อกเป็นตัวแปรในเครื่อง

ตัวแปรที่ประกาศนอกขอบเขตบล็อกและสูงกว่านั้นสามารถเห็นได้ในส่วนหัวของบล็อก (เช่น เงื่อนไขสำหรับ if-block) และภายในบล็อกด้วย โปรแกรมสั้นๆ ต่อไปนี้แสดงสิ่งนี้สำหรับตัวแปร identif:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

intหลัก()
{
intตัวระบุ= 8;

ถ้า (ตัวระบุ== 8)
{
ค่าใช้จ่าย<<ตัวระบุ<<'NS';
}
กลับ 0;
}

ผลลัพธ์คือ 8 มีขอบเขตบล็อกสองส่วนที่นี่: บล็อกสำหรับฟังก์ชัน main() และคำสั่ง if-compound ที่ซ้อนกัน บล็อกที่ซ้อนกันคือขอบเขตที่เป็นไปได้ของบล็อกฟังก์ชัน main()

การประกาศที่นำมาใช้ในขอบเขตของบล็อกไม่สามารถมองเห็นได้ภายนอกบล็อก โปรแกรมสั้นๆ ต่อไปนี้ ซึ่งไม่ได้คอมไพล์ แสดงสิ่งนี้ด้วยตัวแปร Variab:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

intหลัก()
{
ถ้า (1 == 1)
{
intตัวแปร= สิบห้า;
}
ค่าใช้จ่าย<<ตัวแปร<<'NS'; //ข้อผิดพลาด: เข้าถึงได้นอกขอบเขต

กลับ 0;
}

คอมไพเลอร์สร้างข้อความแสดงข้อผิดพลาดสำหรับตัวแปร

เอนทิตีที่แนะนำซึ่งประกาศไว้ในส่วนหัวของฟังก์ชันแบบผสม ไม่สามารถมองเห็นได้ภายนอก (ด้านล่าง) คำสั่งแบบผสม โค้ด for-loop ต่อไปนี้จะไม่คอมไพล์ ส่งผลให้เกิดข้อความแสดงข้อผิดพลาด:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

intหลัก()
{
สำหรับ (intผม=0;ผม<4; ++ผม)
{
ค่าใช้จ่าย<<ผม<<'';
}
ค่าใช้จ่าย<<ผม<<'';

กลับ 0;
}

ตัวแปรการวนซ้ำ i ถูกมองเห็นในบล็อก for-loop แต่ไม่เห็นภายนอกบล็อก for-loop

ขอบเขตฟังก์ชัน

พารามิเตอร์ของฟังก์ชันปรากฏอยู่ในบล็อกฟังก์ชัน เอนทิตีที่ประกาศในบล็อกฟังก์ชันจะมองเห็นได้ตั้งแต่จุดประกาศจนถึงจุดสิ้นสุดของบล็อกฟังก์ชัน โปรแกรมสั้น ๆ ต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
#รวม
โดยใช้ เนมสเปซชั่วโมง;

สตริง fn(สตริง str)
{
charสตริ[] = 'กล้วย';
/*ข้อความอื่นๆ*/
สตริงทั้งหมดStr=NS+สตริ;
กลับรวมStr;
}

intหลัก()
{
string totStr=fn('การกิน ');
ค่าใช้จ่าย<<totStr<<'NS';

กลับ 0;
}

ผลลัพธ์คือ:
กินกล้วย

หมายเหตุ: สามารถดูเอนทิตีที่ประกาศนอกฟังก์ชัน (ด้านบน) ได้ในรายการพารามิเตอร์ของฟังก์ชันและในบล็อกฟังก์ชันด้วย

ฉลาก

ขอบเขตของป้ายกำกับคือฟังก์ชันที่ปรากฏ รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

โมฆะfn()
{
ไปที่labl;
/*ข้อความอื่นๆ*/
labl: intไม่= 2;
ค่าใช้จ่าย<<ไม่<<'NS';
}

intหลัก()
{
fn();

กลับ 0;
}

ผลลัพธ์คือ 2

ขอบเขตการแจงนับ

การแจงนับแบบไม่มีขอบเขต
พิจารณา if-block ต่อไปนี้:

ถ้า (1==1)
{
enum {ก, ข, ค=NS+2};
ค่าใช้จ่าย<<ถึง<<''<<NS<<''<<<<'NS';
}

เอาต์พุตคือ 0 1 3

บรรทัดแรกในบล็อกคือการแจงนับ a, b และ c เป็นตัวแจงนับ ขอบเขตของการแจงนับเริ่มต้นจากจุดประกาศจนถึงจุดสิ้นสุดของบล็อกที่ล้อมรอบของการแจงนับ

คำสั่งต่อไปนี้จะไม่รวบรวมเนื่องจากจุดประกาศของ c อยู่หลังจุดของ a:

enum {ถึง=+2, ข, ค};

ส่วนรหัสต่อไปนี้จะไม่คอมไพล์เนื่องจากมีการเข้าถึงตัวแจงนับหลังจากบล็อกที่ล้อมรอบของการแจงนับ:

ถ้า (1==1)
{
enum {ก, ข, ค=NS+2};
}
ค่าใช้จ่าย<<ถึง<<''<<NS<<''<<<<'NS'; //ข้อผิดพลาด: อยู่นอกขอบเขต

การแจงนับข้างต้นถูกอธิบายว่าเป็นการแจงนับที่ไม่มีขอบเขต และการแจงนับของมันถูกอธิบายว่าเป็นการแจงนับที่ไม่มีขอบเขต เนื่องจากมันขึ้นต้นด้วยเฉพาะคำสงวน enum การแจงนับที่เริ่มต้นด้วยคลาส enum หรือ enum struct ถูกอธิบายว่าเป็นการแจงนับที่มีขอบเขต ตัวแจงนับของพวกมันถูกอธิบายว่าเป็นตัวแจงนับที่มีขอบเขต

การนับขอบเขต
คำสั่งต่อไปนี้ใช้ได้:

enum ระดับชาย{ก, ข, ค=NS+2};

นี่คือตัวอย่างของการแจงนับขอบเขต ชื่อของชั้นคือน้ำ ที่นี่ ขอบเขตของการแจงนับเริ่มต้นจากจุดประกาศจนถึงจุดสิ้นสุดของคำจำกัดความการแจงนับ ไม่ใช่จุดสิ้นสุดของบล็อกล้อมรอบสำหรับการแจงนับ รหัสต่อไปนี้จะไม่คอมไพล์:

ถ้า (1==1)
{
enum ระดับชาย{ก, ข, ค=NS+2};
ค่าใช้จ่าย<<ถึง<<''<<NS<<''<<<<'NS'; // ข้อผิดพลาด: อยู่นอกขอบเขตสำหรับ enum class หรือ enum struct
}

ขอบเขตชั้นเรียน

เมื่อใช้การกำหนดขอบเขตปกติ พื้นที่การประกาศจะเริ่มต้นจากจุดหนึ่ง จากนั้นจึงดำเนินต่อไปและหยุดที่จุดอื่น ขอบเขตมีอยู่ในภูมิภาคเดียวที่ต่อเนื่องกัน กับคลาส ขอบเขตของเอนทิตีสามารถอยู่ในภูมิภาคต่าง ๆ ที่ไม่ได้รวมเข้าด้วยกัน กฎสำหรับบล็อกที่ซ้อนกันยังคงมีผลบังคับใช้ โปรแกรมต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

//คลาสพื้นฐาน
ระดับคลา
{
ส่วนตัว:
intmemP= 5;
มีการป้องกัน:
intmemPro= 9;
สาธารณะ:
โมฆะfn()
{
ค่าใช้จ่าย<<memP<<'NS';
}
};

//คลาสที่ได้รับ
ระดับเดอร์คลา: สาธารณะคลา
{
สาธารณะ:
intderMem=memPro;
};
intหลัก()
{
Cla obj;
วัตถุfn();
DerCla derObj;
ค่าใช้จ่าย<<derObj.derMem<<'NS';

กลับ 0;
}

ผลลัพธ์คือ:
5
9

ในคลาส Cla จะเห็นตัวแปร memP ที่จุดประกาศ หลังจากนั้น จะข้ามส่วนสั้น ๆ ของการป้องกัน แล้วเห็นอีกครั้งในบล็อกฟังก์ชันสมาชิกของคลาส คลาสที่ได้รับถูกข้ามไป จากนั้นเห็นอีกครั้งที่ขอบเขตฟังก์ชัน main() (บล็อก)

ในคลาส Cla คือตัวแปร memPro ที่จุดประกาศ ส่วนของฟังก์ชันสาธารณะ fn() ถูกข้ามไป จากนั้นจะเห็นได้ในบล็อกคำอธิบายคลาสที่ได้รับ จะเห็นอีกครั้งในฟังก์ชัน main()

ตัวดำเนินการแก้ไขขอบเขต
ตัวดำเนินการความละเอียดขอบเขตใน C++ คือ :: มันถูกใช้เพื่อเข้าถึงสมาชิกแบบคงที่ของคลาส โปรแกรมต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

ระดับคลา
{
สาธารณะ:
คงที่ int constมีม= 5;
สาธารณะ:
คงที่ โมฆะfn()
{
ค่าใช้จ่าย<<มีม<<'NS';
}
};
intหลัก()
{
ค่าใช้จ่าย<<คลา::มีม<<'NS';
คลา::fn();

กลับ 0;
}

ผลลัพธ์คือ:
5
5

สมาชิกแบบคงที่จะเห็นได้ในบล็อกฟังก์ชัน main() ซึ่งเข้าถึงได้โดยใช้ตัวดำเนินการแก้ไขขอบเขต

ขอบเขตพารามิเตอร์เทมเพลต

ขอบเขตปกติของชื่อพารามิเตอร์เทมเพลตเริ่มต้นจากจุดประกาศจนถึงจุดสิ้นสุดของบล็อกดังในโค้ดต่อไปนี้:

แม่แบบ<พิมพ์ชื่อNS,พิมพ์ชื่อยู> โครงสร้างอายุ
{
ที จอห์น= สิบเอ็ด;
คุณปีเตอร์= 12.3;
ที แมรี่= 13;
ยูจอย= 14.6;
};

U และ T ถูกมองเห็นภายในบล็อก

สำหรับต้นแบบฟังก์ชันต้นแบบ ขอบเขตเริ่มต้นจากจุดประกาศจนถึงจุดสิ้นสุดของรายการพารามิเตอร์ฟังก์ชัน ดังในข้อความสั่งต่อไปนี้:

แม่แบบ<พิมพ์ชื่อNS,พิมพ์ชื่อยู> โมฆะการทำงาน(คุณ ไม่ คุณชาconst char *NS);

อย่างไรก็ตาม เมื่อพูดถึงคำอธิบายคลาส (คำจำกัดความ) ขอบเขตสามารถเป็นส่วนต่าง ๆ ตามโค้ดต่อไปนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

แม่แบบ<ระดับNS,ระดับยู> ระดับTheCla
{
สาธารณะ:
t num;
คงที่ยูช;

โมฆะการทำงาน(คุณ พ่อconst char *NS)
{
ค่าใช้จ่าย << 'มี' <<หนึ่ง<< 'หนังสือคุ้ม' <<ไม่<<NS<< ' ในร้าน.' << 'NS';
}
คงที่ โมฆะสนุก(ยูช)
{
ถ้า (ch== 'ถึง')
ค่าใช้จ่าย << 'ฟังก์ชั่นสมาชิกคงที่อย่างเป็นทางการ' << 'NS';
}
};

intหลัก()
{
TheCla<int,char>วัตถุ;
วัตถุหนึ่ง = 12;
วัตถุการทำงาน('$','500');

กลับ 0;
}

ซ่อนชื่อ

ตัวอย่างของการซ่อนชื่อเกิดขึ้นเมื่อมีการประกาศชื่อของประเภทวัตถุเดียวกันอีกครั้งในบล็อกที่ซ้อนกัน โปรแกรมต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

โมฆะfn()
{
intที่ไหน= 3;
ถ้า (1==1)
{
intที่ไหน= 4;
ค่าใช้จ่าย<<ที่ไหน<<'NS';
}
ค่าใช้จ่าย<<ที่ไหน<<'NS';
}

intหลัก()
{
fn();
กลับ 0;
}

ผลลัพธ์คือ:
4
3

เป็นเพราะ var ในบล็อกที่ซ้อนกัน hid var ในบล็อกด้านนอก

ความเป็นไปได้ของการประกาศซ้ำในขอบเขตเดียวกัน

ประเด็นของการประกาศคือตำแหน่งที่มีการแนะนำชื่อ (เป็นครั้งแรก) ในขอบเขต

ต้นแบบฟังก์ชัน
โดยปกติ เอนทิตีที่ต่างกัน แม้จะต่างกันคนละประเภท จะไม่สามารถประกาศในขอบเขตเดียวกันได้ อย่างไรก็ตาม ต้นแบบฟังก์ชันสามารถประกาศได้มากกว่าหนึ่งครั้งในขอบเขตเดียวกัน โปรแกรมต่อไปนี้ที่มีต้นแบบฟังก์ชันสองตัวและการกำหนดฟังก์ชันที่เกี่ยวข้องจะแสดงสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

โมฆะfn(intหนึ่ง);
โมฆะfn(intหนึ่ง);

โมฆะfn(intหนึ่ง)
{
ค่าใช้จ่าย<<หนึ่ง<<'NS';
}

intหลัก()
{
fn(5);

กลับ 0;
}

โปรแกรมทำงาน

ฟังก์ชั่นโอเวอร์โหลด
ฟังก์ชันโอเวอร์โหลดคือฟังก์ชันที่มีชื่อเดียวกัน แต่มีลายเซ็นฟังก์ชันต่างกัน เป็นข้อยกเว้นอีกประการหนึ่ง ฟังก์ชันโอเวอร์โหลดที่มีชื่อเดียวกันสามารถกำหนดในขอบเขตเดียวกันได้ โปรแกรมต่อไปนี้แสดงให้เห็นสิ่งนี้:

#รวม
โดยใช้ เนมสเปซชั่วโมง;

โมฆะfn(intหนึ่ง)
{
ค่าใช้จ่าย<<หนึ่ง<<'NS';
}

โมฆะfn(ลอยไม่)
{
ค่าใช้จ่าย<<ไม่<<'NS';
}

intหลัก()
{
fn(5);
ลอยflt= 8.7;
fn(flt);

กลับ 0;
}

ผลลัพธ์คือ:
5
8.7

มีการกำหนดฟังก์ชันโอเวอร์โหลดในขอบเขตส่วนกลาง

ขอบเขตเนมสเปซ

Namespace Scope สมควรได้รับบทความของตัวเอง บทความดังกล่าวเขียนขึ้นสำหรับเว็บไซต์นี้ linuxhint.com เพียงพิมพ์คำค้นหา Namespace Scope ในช่องค้นหาของเว็บไซต์นี้ (หน้า) แล้วคลิกตกลง คุณก็จะได้บทความ

ขอบเขตในส่วนต่างๆ

คลาสไม่ใช่แบบแผนเดียวที่ขอบเขตสามารถอยู่ในส่วนต่างๆ ได้ ตัวระบุเพื่อน การใช้งานบางอย่างของตัวระบุประเภทที่ซับซ้อน และคำสั่งการใช้คือรูปแบบอื่นๆ ที่ขอบเขตอยู่ในที่ต่างๆ - สำหรับรายละเอียด โปรดดูในภายหลัง

บทสรุป

ขอบเขตคือพื้นที่ประกาศ ภูมิภาคประกาศเป็นส่วนที่ใหญ่ที่สุดของข้อความโปรแกรมซึ่งชื่อของเอนทิตีถูกต้อง สามารถแบ่งออกเป็นหลายส่วนตามรูปแบบการเขียนโปรแกรมบางอย่าง เช่น บล็อกที่ซ้อนกัน ส่วนที่ไม่มีจุดประกาศสร้างขอบเขตที่เป็นไปได้ ขอบเขตที่เป็นไปได้อาจมีหรือไม่มีการประกาศ