© FOTOGRIN/Shutterstock.com
ในฐานะภาษาโปรแกรมเชิงวัตถุ C++ มักจะใช้การสืบทอด คุณลักษณะนี้ทำให้คุณสามารถแก้ไขและนำแอตทริบิวต์และคุณลักษณะอื่นๆ ของคลาสกลับมาใช้ใหม่ได้ รวมทั้งลดจำนวนโค้ดที่คุณต้องการ อ่านต่อเพื่อดูว่าการสืบทอดคืออะไรและประเภทของการสืบทอดใน C++ ที่คุณสามารถใช้ได้
การสืบทอดคืออะไร
มากในวิธีที่เราสามารถ”สืบทอด”ลักษณะเฉพาะบางอย่างได้ จากพ่อแม่ของเรา ในคลาส C++ สามารถสืบทอดสมาชิกจากคลาสอื่นได้ ด้วยวิธีนี้ คลาสที่มีสมาชิกได้รับการสืบทอดจะถูกกำหนดเป็นคลาสหลักหรือคลาสหลัก และคลาสที่สืบทอดคุณสมบัติเหล่านี้เรียกว่าคลาสที่ได้รับ คลาสย่อย หรือคลาสย่อย เนื่องจากสิ่งนี้ทำให้สามารถใช้สมาชิกของคลาสพาเรนต์ซ้ำได้ สมาชิกเหล่านี้จึงไม่จำเป็นต้องถูกกำหนดใหม่ ดังนั้น คุณจึงประหยัดเวลาในการใช้โค้ดที่ไม่จำเป็นได้
ฟังก์ชันเพื่อนและคลาสเพื่อนมีความคล้ายคลึงกัน เนื่องจากฟังก์ชันและคลาสเหล่านี้อนุญาตให้ฟังก์ชันและคลาสเข้าถึงสมาชิกของคลาสอื่นได้ อย่างไรก็ตาม เพื่อนอนุญาตให้เข้าถึงสมาชิกส่วนตัวได้ ในขณะที่การสืบทอดไม่อนุญาต
ประเภทของการสืบทอดใน C++ คืออะไร
การสืบทอดใน C++ มี 5 ประเภท สิ่งเหล่านี้คือ:
การสืบทอดแบบเดี่ยวการสืบทอดแบบหลายระดับการสืบทอดแบบหลายระดับการสืบทอดแบบไฮบริดการสืบทอดแบบลำดับชั้น
ลองมาดูแต่ละรายการเหล่านี้
การสืบทอดแบบเดี่ยว
วิธีการสืบทอดที่ง่ายที่สุดคือการที่คลาสหนึ่ง สืบทอดสมาชิกของคลาสอื่น สามารถแสดงได้ด้วยโค้ดต่อไปนี้:
#include class BaseClass { public: int x; }; คลาส DerivedClass: สาธารณะ BaseClass{ สาธารณะ: int y; }; int หลัก () { DerivedClass obj; obj.x=10 obj.y=20 std::cout”ตัวแปรสมาชิกคลาสพื้นฐาน x=”std::endl; std::cout”ตัวแปรสมาชิกคลาสที่ได้รับ y=”obk.y std::endl; กลับ 0; }
ที่นี่ เราได้กำหนดคลาสพื้นฐานเป็น”BaseClass”โดยมีสมาชิกเป็น”x”ที่เข้าถึงได้แบบสาธารณะ คลาสที่ได้รับถูกกำหนดให้เป็น”DerivedClass”ซึ่งสืบทอดมาจาก”BaseClass”แบบสาธารณะ คลาสที่ได้รับนั้นมีสมาชิกสาธารณะที่เรียกว่า”y”เราสร้างอินสแตนซ์ของคลาสที่ได้รับชื่อ “DerivedClass obj” และตั้งค่า x และ y เมื่อใช้วัตถุนี้ เราเข้าถึงสมาชิก “x” จากคลาสพาเรนต์ และค่า x และ y จะถูกพิมพ์ไปยังคอนโซลตามที่แสดงในภาพหน้าจอ
การสืบทอดแบบเดี่ยวที่แสดงในตัวอย่าง
©”TNGD”.com
สืบทอดสมาชิกส่วนตัว
เป็นที่น่าสังเกตว่าคลาสที่ได้รับมาสามารถสืบทอดสมาชิกทั้งหมดของคลาสพาเรนต์ได้เนื่องจากพวกเขามีสิทธิ์เข้าถึงแบบสาธารณะ อย่างไรก็ตาม หากสมาชิกถูกประกาศเป็นส่วนตัว ก็จะไม่สามารถสืบทอดโดยตรงได้ วิธีแก้ไขคือหากฟังก์ชันบางอย่างที่ดำเนินการกับสมาชิกเหล่านี้ได้รับการสืบทอดมา ด้วยวิธีนี้ คุณจะสามารถเข้าถึงสมาชิกเหล่านี้ได้ทางอ้อม ใช้ตัวอย่างต่อไปนี้:
class Base{ ส่วนตัว: int a; สาธารณะ: ฐาน (int a) a (a) {} int getA() const { return a; } }; คลาสที่ได้มา: ฐานสาธารณะ { สาธารณะ: สืบทอดมา (int a): ฐาน (A) {} }; int main() { มาจาก d(5); std::cout”ค่าของวัตถุที่ได้รับ:”d.getA() std::endl; กลับ 0; }
ที่นี่ เราได้กำหนดคลาสพาเรนต์เป็น”ฐาน”และคลาสที่ได้รับเป็น”มา”สมาชิก”a”ของคลาสพาเรนต์เป็นแบบส่วนตัว ดังนั้นคลาสที่ได้รับมาจะไม่สามารถเข้าถึงได้โดยตรง แต่เรามีตัวสร้างในคลาสพื้นฐานซึ่งรับอาร์กิวเมนต์จำนวนเต็มของ”a”และตั้งค่าสมาชิกส่วนตัว”a”คลาสที่ได้รับมีตัวสร้างเอง”Derived(int a): Base (a) {}”ซึ่งรับอาร์กิวเมนต์จำนวนเต็ม”a”และส่งต่อไปยังตัวสร้างของคลาสฐาน เนื่องจากฟังก์ชัน”getA()”ได้รับการสืบทอดมา ดังนั้นการเข้าถึงสมาชิก”a”ของคลาสพาเรนต์โดยอ้อมจึงสำเร็จ
การใช้ฟังก์ชัน”main”เราจะใช้อินสแตนซ์”d”ของ คลาสที่ได้รับและกำหนดด้วยอาร์กิวเมนต์ 5 ฟังก์ชัน”getA()”ถูกเรียกในอินสแตนซ์นี้ และเอาต์พุตจะถูกพิมพ์ ซึ่งแสดงอยู่ในภาพหน้าจอ
วิธีสืบทอดสมาชิกส่วนตัวดังตัวอย่าง
©”TNGD”.com
คลาสส่วนตัวเทียบกับคลาสที่มีการป้องกัน
ขั้นตอนนี้น่าจะคุ้มค่าที่จะ แยกความแตกต่างระหว่างคลาสส่วนตัวและคลาสที่มีการป้องกัน ในขณะที่สมาชิกคลาสไพรเวตสามารถเข้าถึงได้ทางอ้อมโดยคลาสที่ได้รับมาเท่านั้น สมาชิกคลาสที่ได้รับการป้องกันสามารถเข้าถึงได้โดยสมบูรณ์จากคลาสที่ได้รับ แต่สามารถเข้าถึงได้ภายในลำดับชั้นของคลาสนี้เท่านั้น และไม่สามารถอยู่ภายนอกได้ (ซึ่งจะเป็นการเข้าถึงแบบสาธารณะ)
การสืบทอดเมธอดเท่านั้น
ตัวอย่างเหล่านี้ยังแสดงการสืบทอดฟิลด์ด้วย ที่ฟิลด์”a”ได้รับการสืบทอด แต่คุณยังสามารถมีการสืบทอดเฉพาะเมธอด โดยเมธอดใช้เพื่อกำหนดพฤติกรรมของคลาส ตัวอย่างด้านล่างนี้:
#inlude class Base { public: virtual void bar() { std::cout”Base::bar()”std::endl; } }; คลาสที่ได้รับ: ฐานสาธารณะ { สาธารณะ: แถบโมฆะเสมือน () { std::cout”ได้รับ:: บาร์ ()”std::endl; } }; int main() { ฐาน* b=ใหม่ที่ได้มา (); b->แถบ ();//เอาต์พุต”Derived::bar()”ลบ b; กลับ 0; }
เช่นเดิม เรามีคลาสหลัก”ฐาน”และคลาสที่ได้รับ”มา”“Base” มีเมธอดเสมือน “bar()” สิ่งนี้เรียกว่าเสมือนเนื่องจากไม่มีการใช้งานในคลาสพาเรนต์ และสามารถถูกแทนที่โดยคลาสที่ได้รับ การใช้งานหากมีการระบุ”bar()”ในคำจำกัดความของคลาสที่ได้รับ เราจะเห็นว่าตัวชี้”b”ถูกสร้างขึ้นภายในฟังก์ชัน”main()”และเริ่มต้นด้วยวัตถุ”Derived”“Derived::bar()” แทนที่ “Base::bar()” เนื่องจากเป็นฟังก์ชันเสมือน การใช้งานภายในคลาสที่ได้รับเรียกว่า ซึ่งจะพิมพ์ผลลัพธ์ “Derived::bar()” ตามที่เห็นในภาพหน้าจอ
ตัวอย่างที่แสดงการสืบทอดเฉพาะเมธอด
©”TNGD”.com
การสืบทอดหลายระดับ
มีหลายกรณีที่คุณอาจต้องการสร้างคลาสที่ได้รับมาจากคลาสที่ได้รับมาจากคลาสพาเรนต์แล้ว สิ่งนี้เรียกว่าการสืบทอดหลายระดับ เท่าที่ประเภทของการสืบทอดใน C ++ ดำเนินไป สิ่งนี้ค่อนข้างใช้งานง่าย ตัวอย่างหนึ่งคือเมื่อคุณทำงานกับประเภทยานพาหนะ ในสถานการณ์นี้ คุณอาจมีคลาสหลักของ”ยานพาหนะ”ซึ่งกำหนดวิธีการและพารามิเตอร์บางอย่างที่เป็นสากลสำหรับยานพาหนะที่คุณกำลังทำงานด้วย เช่น รถยนต์และมอเตอร์ไซค์ สิ่งเหล่านี้อาจเป็นคลาสที่ได้รับมาจากคลาสพาเรนต์นี้ ซึ่งมีคุณสมบัติเฉพาะของมันเอง แต่เนื่องจากคุณอาจมีประเภทของสิ่งเหล่านี้โดยเฉพาะ คุณจึงสามารถสร้างคลาสที่ได้รับมา เช่น “PerformanceCar” ซึ่งจะมีคุณสมบัติที่เกี่ยวข้องเป็นของตัวเอง
เราสามารถแสดงวิธีการทำงานด้วยโค้ดต่อไปนี้:
#include #include class Vehicle { สาธารณะ: std::string ประเภท; std::สีสตริง; }; รถคลาส: ยานพาหนะสาธารณะ { สาธารณะ: std::string model; ภายในปี; }; คลาส ElectricCar: รถสาธารณะ { สาธารณะ: int batteryCapacity; }; int หลัก () { ElectricCar เทสลา; tesla.type=”รถยนต์ไฟฟ้า”; tesla.color=”สีแดง”; tesla.model=”รุ่น S”; เทสลาปี=2021; tesla.batteryCapacity=100; std::cout”ประเภท:”tesla.type std::endl; std::cout”สี:”tesla.color std::endl; std::cout”Model:”tesla.model std::endl; std::cout”Year:”tesla.year std::endl; std::cout”ความจุของแบตเตอรี่:”tesla.batteryCapacity std::endl; กลับ 0; }
ในตัวอย่างนี้ เรามีคลาสพื้นฐาน”ยานพาหนะ”คลาสที่ได้รับมา”รถยนต์”และคลาสที่ได้รับมาเพิ่มเติมเรียกว่า”รถยนต์ไฟฟ้า”คลาส”Vehicle”มีสมาชิก”type”และ”color”คลาส”Car”มีสมาชิกเป็น”model”และตัวแปรจำนวนเต็ม”ปี”และคลาส”ElectricCar”มีตัวแปรสมาชิกจำนวนเต็ม”batteryCapacity”ฟังก์ชันหลักสร้างอินสแตนซ์ของคลาส”ElectricCar”โดยตั้งค่าตัวแปรสมาชิกที่สืบทอดมาทั้งหมดด้วยค่าเฉพาะ จากนั้นตัวแปรเหล่านี้จะพิมพ์ไปที่คอนโซล
ใช้งานการสืบทอดหลายระดับในตัวอย่าง ร่วมกับผลลัพธ์ของมัน
©”TNGD”.com
การสืบทอดหลายระดับ
เช่นเดียวกับที่เราได้รับคลาสมา จากคลาสที่ได้รับมาแล้ว เราสามารถมีคลาสที่มาจากคลาสพื้นฐานมากกว่าหนึ่งคลาส เราสามารถแสดงให้เห็นได้โดยดำเนินการเปรียบเทียบรถยนต์ของเราต่อไป:
#include #include class Vehicle { public: std::string type; std::สีสตริง; }; คลาส ElectricEngine { สาธารณะ: int batteryCapacity; }; คลาส SportsCar { สาธารณะ: int topSpeed; }; คลาส ElectricSportsCar: ยานพาหนะสาธารณะ ElectricEngine สาธารณะ SportsCar สาธารณะ { สาธารณะ: std::string model; ภายในปี; }; int main() { เทสลา ElectricSportsCar; tesla.type=”รถยนต์ไฟฟ้า”; tesla.color=”สีแดง”; tesla.model=”รถเปิดประทุน”; เทสลาปี=2022; tesla.batteryCapacity=200; tesla.topSpeed =250; std::cout”ประเภท:”tesla.type std::endl; std::cout”สี:”tesla.color std::endl; std::cout”Model:”tesla.model std::endl; std::cout”Year:”tesla.year std::endl; std::cout”ความจุของแบตเตอรี่:”tesla.batteryCapacity”kWh”std::endl; std::cout”ความเร็วสูงสุด:”tesla.topSpeed ”mph”std::endl; กลับ 0; }
เรามีสามคลาสที่นี่”ยานพาหนะ””เครื่องยนต์ไฟฟ้า”และ”สปอร์ตคาร์”สิ่งเหล่านี้เป็นคลาสพื้นฐานทั้งหมด และมีคุณสมบัติที่สืบทอดมาจากคลาสที่ได้รับมา “ElectricSportsCar” ก่อนหน้านี้แต่ละคลาสหลักมีตัวแปรของตัวเอง มีการสร้างอินสแตนซ์ของ “ElectricSportsCar” ค่าต่างๆ จะถูกกำหนดให้กับคุณสมบัติของมัน และค่าเหล่านี้จะถูกพิมพ์ไปยังคอนโซล
ตัวอย่างการสืบทอดหลายรายการ
©”TNGD”.com
การสืบทอดแบบลำดับชั้น
เรากำลังถึงจุดสิ้นสุดของการสืบทอดประเภทต่างๆ ใน C++ นี่คือจุดที่สถานการณ์เหมาะสมยิ่งขึ้นเล็กน้อย แม้ว่าการสืบทอดหลายระดับในทางเทคนิคจะสร้างลำดับชั้น แต่สิ่งนี้แตกต่างจากสิ่งที่เรียกว่าการสืบทอดลำดับชั้น หากคุณกำลังสร้างคลาสที่ได้รับมาหลายคลาสจากคลาสพาเรนต์เดียว สิ่งนี้เรียกว่าการสืบทอดแบบลำดับชั้น สิ่งนี้มีประโยชน์เมื่อคุณต้องการสร้างคลาสที่เกี่ยวข้องจากคลาสพาเรนต์ แต่แต่ละคลาสจะมีคุณสมบัติของตัวเอง โค้ดด้านล่างแสดงตัวอย่างนี้
class Vehicle { public: std::string type; std::สีสตริง; }; รถคลาส: ยานพาหนะสาธารณะ { สาธารณะ: std:: รุ่นสตริง; ภายในปี; }; รถบรรทุกคลาส: ยานพาหนะสาธารณะ { สาธารณะ: ความจุ int; };
อีกครั้ง เรามีคลาสหลัก”ยานพาหนะ”และทั้งคลาส”รถยนต์”และ”รถบรรทุก”ก็มาจากคลาสนี้ คลาสทั้งสองนี้สืบทอดตัวแปร”ประเภท”และสี แต่เพิ่มคุณสมบัติของตัวเองเช่นกัน ได้แก่”รุ่น”และ”ปี”สำหรับคลาส”รถยนต์”และ”ความจุ”สำหรับคลาส”รถบรรทุก”ในภาพหน้าจอแรก เราสามารถเห็นรหัสที่ใช้กับฟังก์ชัน “main()” โดยมีอินสแตนซ์ของแต่ละคลาสที่สร้างขึ้นและชุดแอตทริบิวต์ของคลาสนั้น ภาพหน้าจอที่สองแสดงเอาต์พุตในคอนโซล
ใช้การสืบทอดแบบลำดับชั้นในคลาส
©”TNGD”.com
ผลลัพธ์ของตัวอย่างข้างต้น
©”TNGD”.com
การสืบทอดแบบไฮบริด
สถานการณ์จะซับซ้อนขึ้นเล็กน้อยเมื่อพูดถึงการสืบทอดแบบไฮบริด นี่คือที่ที่การสืบทอดประเภทต่าง ๆ ใน C ++ ถูกรวมเข้าด้วยกันในลำดับชั้นเดียว แม้ว่าสิ่งนี้จะซับซ้อน แต่บางครั้งก็จำเป็นสำหรับการดำเนินการที่คุณต้องดำเนินการ พิจารณาสถานการณ์ต่อไปนี้:
#include #include class Vehicle { public: std::string type; std:: สีสตริง; }; เครื่องยนต์คลาส { สาธารณะ: int แรงม้า; }; รถคลาส: ยานพาหนะสาธารณะ, เครื่องยนต์สาธารณะ { สาธารณะ: std::string model; ภายในปี; }; คลาส ElectricCar: รถสาธารณะ { สาธารณะ: int batteryCapacity; }; ใน main() { ElectricCar เทสลา; tesla.type=”รถยนต์ไฟฟ้า”; tesla.color=”สีแดง”; tesla.model=”รุ่น S”; เทสลา แรงม้า=300; เทสลาปี=2021; tesla.batteryCapacity=100; tesla.type=”รถยนต์ไฟฟ้า”; std::cout”ประเภท:”tesla.type std::endl; std::cout”สี:”tesla.color std::endl; std::cout”แรงม้า:”tesla.horsepower std::endl; std::cout”Model:”tesla.model std::endl; std::cout”ปี:”tesla.year std::endl; std::cout”ความจุของแบตเตอรี่:”tesla.batteryCapacity std::endl; กลับ 0; }
เช่นเดิม เรามีคลาสพาเรนต์”Vehicle”แต่ยังมีคลาสพาเรนต์”Engine”ด้วย เรามีตัวอย่างการสืบทอดหลายอย่าง โดยที่คลาส”รถยนต์”มาจากทั้งคลาส”ยานพาหนะ”และ”เครื่องยนต์”จากนั้นคลาส”ElectricCar”จะมาจากคลาส”รถยนต์”ซึ่งเป็นตัวอย่างของการสืบทอดหลายระดับ เนื่องจากเป็นประเภทรถยนต์เฉพาะทางมากกว่า ดังนั้นเราจึงมีสถานการณ์ที่การสืบทอดแบบไฮบริดเกิดขึ้น ด้วยเหตุนี้ การสืบทอดแบบไฮบริดจึงมีประโยชน์ในการช่วยลดความซับซ้อนและเข้าใจความสัมพันธ์ที่ซับซ้อน รวมถึงทำให้โค้ดดูแลรักษาได้ง่ายขึ้น
ภาพแรกแสดงการนำโค้ดไปใช้ ซึ่งเราได้สร้างอินสแตนซ์ของ คลาส “ElectricCar” ที่มีแอตทริบิวต์ตั้งจากคลาสหลักทั้งหมด ผลลัพธ์ที่พิมพ์จะแสดงในรูปที่สอง
ใช้การสืบทอดแบบไฮบริดในคลาส
©”TNGD”.com
ผลลัพธ์ของตัวอย่างข้างต้น
©”TNGD”.com
หมายเหตุเกี่ยวกับความกำกวม
ปัญหาที่พบบ่อยมากที่สามารถเกิดขึ้นเมื่อต้องจัดการกับหลายคลาสคือปัญหาของความกำกวม นี่คือที่ที่คุณมีตัวแปรสมาชิกหรือฟังก์ชันที่เหมือนกันในสองคลาสขึ้นไป จากนั้นคอมไพลเลอร์อาจพบข้อผิดพลาดเนื่องจากไม่สามารถตัดสินใจได้ว่าจะใช้สมาชิกใดสำหรับการดำเนินการที่คุณกำลังพยายามเรียกใช้ พิจารณาโค้ดต่อไปนี้:
#include class A { public: void foo() {std::cout”A:foo()”std::endl;} }; คลาส B { สาธารณะ: โมฆะ foo() {std::cout”B::foo()”std::endl;} }; คลาส C: สาธารณะ A, สาธารณะ B { สาธารณะ: }; int main() { คค; ค.ฟู();//ข้อผิดพลาดของคอมไพเลอร์: การเรียกที่ไม่ชัดเจนไปยัง foo() จาก A และ B ส่งคืน 0; }
ที่นี่ เรามีฟังก์ชันชื่อ”foo()”ทั้งในคลาส”A”และคลาส”B”เนื่องจากคลาส “C” สืบทอดมาจากทั้งสองคลาสนี้ จึงเกิดข้อผิดพลาดระหว่างการคอมไพล์ สิ่งนี้สามารถแก้ไขได้หลายวิธี:
เปลี่ยนชื่อฟังก์ชันหรือตัวแปรที่ขัดแย้งกันในคลาสพาเรนต์หรือคลาสที่ได้รับเพื่อหลีกเลี่ยงความสับสน การใช้โอเปอเรเตอร์การแก้ไขขอบเขต (::) เพื่อระบุคลาสที่มีฟังก์ชันสมาชิกที่ต้องการ การสืบทอดเสมือนทำงานบนแนวคิดที่คล้ายคลึงกับฟังก์ชันเสมือนที่กล่าวถึงก่อนหน้านี้ สิ่งนี้สามารถอนุญาตให้คลาสที่ได้รับมาสืบทอดจากคลาสพาเรนต์โดยไม่ต้องทำซ้ำคลาสพื้นฐานที่พาเรนต์เหล่านี้ใช้ร่วมกัน การแทนที่ฟังก์ชันที่ขัดแย้งกันโดยการกำหนดฟังก์ชันใหม่ในคลาสที่ได้รับด้วยการใช้งานพิเศษ แสดงข้อผิดพลาดที่ไม่ชัดเจน
©”TNGD”.com
บทสรุป
มี 5 ประเภทหลักของการสืบทอดใน C++ ที่คุณสามารถใช้ได้ โดยแต่ละประเภทมีกรณีการใช้งานเฉพาะของตัวเอง แม้ว่าการสืบทอดแบบเดี่ยวอาจเหมาะสำหรับการดำเนินการที่ค่อนข้างง่าย แต่เมื่อทำงานกับวัตถุและความสัมพันธ์ที่ซับซ้อน การสืบทอดประเภทอื่นๆ เช่น การสืบทอดหลายระดับ หลายระดับ ลำดับชั้น และแบบผสมอาจเหมาะสมกว่า สิ่งเหล่านี้มีประโยชน์ในการทำให้โค้ดใช้งานง่ายขึ้นและดูแลรักษาง่ายขึ้น รวมถึงแสดงความสัมพันธ์ระหว่างคลาสได้ดีขึ้น
อธิบายการสืบทอดใน C++ พร้อมตัวอย่าง คำถามที่พบบ่อย (คำถามที่พบบ่อย)
คลาสพาเรนต์และคลาสที่ได้รับมาคืออะไร
คลาสพาเรนต์หรือที่เรียกว่าคลาสพื้นฐานคือคลาสที่สืบทอดมา ในทางกลับกัน คลาสที่ได้รับ คลาสย่อย หรือคลาสย่อยจะสืบทอดคุณสมบัติและแอตทริบิวต์จากคลาสพาเรนต์
การสืบทอดในภาษา C++ คืออะไร
การสืบทอด เป็นกระบวนการที่ให้คุณสร้างคลาสที่ได้รับจากคลาสแม่หรือคลาสพื้นฐาน ซึ่งสืบทอดคุณสมบัติและฟังก์ชันสมาชิกจากคลาสพาเรนต์ สิ่งนี้มีประโยชน์ในการแสดงความสัมพันธ์ที่ซับซ้อนและลดความจำเป็นในการติดตั้งโค้ดซ้ำ
การสืบทอดประเภทต่างๆ ใน C++ มีอะไรบ้าง
มี การสืบทอดหลัก 5 ประเภทใน C++ – แบบเดี่ยว หลายระดับ หลายระดับ ลำดับชั้น และแบบผสม Single และ Multiple หมายถึงคลาสเดียวที่ได้มาจากคลาสพื้นฐานหนึ่งคลาสหรือมากกว่าหนึ่งคลาสตามลำดับ การสืบทอดหลายระดับหมายถึงเมื่อคลาสได้รับมาจากคลาสที่ได้รับมา การสืบทอดแบบลำดับชั้นหมายถึงเมื่อคลาสหลายคลาสได้รับมาจากคลาสพื้นฐานหนึ่งคลาส และการสืบทอดแบบไฮบริดหมายถึงการใช้ประเภทอื่นๆ เหล่านี้ผสมกัน
คุณใช้การสืบทอดใน C++ อย่างไร
ในการสร้างคลาสที่สืบทอดจากคลาสพาเรนต์ ให้ใช้เครื่องหมายทวิภาค (:) ตามด้วยตัวระบุการเข้าถึง (ในกรณีนี้จะเป็นแบบสาธารณะหรือแบบป้องกัน) และชื่อคลาสพื้นฐาน
>สมาชิกสาธารณะ สมาชิกที่ได้รับการคุ้มครอง และสมาชิกส่วนตัวคืออะไร
สมาชิกสาธารณะสามารถมองเห็นได้อย่างสมบูรณ์และเข้าถึงได้จากทุกที่ภายในโปรแกรม และสามารถเข้าถึงได้โดยฟังก์ชันใดๆ ภายในหรือภายนอกชั้นเรียน. สมาชิกที่ได้รับการป้องกันสามารถเข้าถึงได้โดยคลาสที่ได้รับ ดังนั้นจึงสามารถสืบทอดได้ สมาชิกส่วนตัวไม่สามารถเข้าถึงได้โดยฟังก์ชันใดๆ ภายนอกคลาส และมองไม่เห็นในคลาสที่ได้รับมา อย่างไรก็ตาม สมาชิกส่วนตัวอาจเป็นทางอ้อมได้หากฟังก์ชันสาธารณะที่ดำเนินการกับพวกเขาได้รับการสืบทอด
ความแตกต่างระหว่างการสืบทอดสาธารณะ ส่วนตัว และการสืบทอดที่ได้รับการปกป้อง
การสืบทอดสาธารณะคือการที่สมาชิกสาธารณะทั้งหมดของคลาสพื้นฐานกลายเป็นสมาชิกสาธารณะของคลาสที่ได้รับมา และในทำนองเดียวกันกับสมาชิกที่ได้รับการคุ้มครองและสมาชิกส่วนตัว การสืบทอดที่ได้รับการคุ้มครองเป็นที่ที่ทั้งสมาชิกสาธารณะและสมาชิกที่ได้รับการคุ้มครองได้รับการสืบทอด แต่สมาชิกส่วนตัวยังคงไม่สามารถเข้าถึงได้ การสืบทอดส่วนตัวหมายความว่าสมาชิกสาธารณะและสมาชิกที่ได้รับการคุ้มครองกลายเป็นสมาชิกส่วนตัวของคลาสที่ได้รับมา และเช่นเคย สมาชิกส่วนตัวยังคงมองไม่เห็น
คุณจะแก้ไขความคลุมเครือในการสืบทอดได้อย่างไร
คุณสามารถแก้ไขความกำกวมได้โดยใช้ตัวสร้างความละเอียดของขอบเขต ใช้การสืบทอดเสมือน หรือโดยการเปลี่ยนชื่อหรือกำหนดฟังก์ชันที่ขัดแย้งกันใหม่