คำถามในหัวข้อนี้แสดงให้เห็นถึงความสับสนทั่วไป ความสับสนเป็นเรื่องปกติมากพอที่C ++ คำถามที่พบบ่อยสนับสนุนการใช้ virtual private private เป็นเวลานานเนื่องจากความสับสนดูเหมือนจะเป็นสิ่งที่ไม่ดี
ดังนั้นเพื่อกำจัดความสับสนก่อน: ใช่ฟังก์ชั่นเสมือนส่วนตัวสามารถถูกแทนที่ในชั้นเรียนที่ได้รับ วิธีการเรียนที่ได้รับไม่สามารถเรียกฟังก์ชั่นเสมือนจากชั้นฐาน แต่พวกเขาสามารถให้การใช้งานของพวกเขาเองสำหรับพวกเขา อ้างอิงจาก Herb Sutter การมีส่วนต่อประสานแบบ non-virtual สาธารณะในคลาสพื้นฐานและการใช้งานส่วนตัวที่สามารถปรับแต่งได้ในคลาสที่ได้รับอนุญาตให้ "แยกสเปคของอินเตอร์เฟสได้จากสเปคของพฤติกรรมที่ปรับใช้งานได้" คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ในบทความ"Virtuality" ของเขา
อย่างไรก็ตามมีสิ่งหนึ่งที่น่าสนใจในรหัสที่คุณแสดงซึ่งสมควรได้รับความสนใจเพิ่มขึ้นในความคิดของฉัน ส่วนต่อประสานสาธารณะประกอบด้วยชุดของฟังก์ชั่นที่ไม่ได้โอเวอร์โหลดและฟังก์ชั่นเหล่านั้นเรียกฟังก์ชั่นเสมือนที่ไม่ได้เปิดเผยต่อสาธารณะและไม่โอเวอร์โหลด ตามปกติในโลก C ++ มันเป็นสำนวนมันมีชื่อและแน่นอนว่ามันมีประโยชน์ ชื่อคือ (แปลกใจประหลาดใจ!)
"Public Non-Virtuals ที่โอเวอร์โหลดที่มีการป้องกันการโทรเสมือนที่ไม่โอเวอร์โหลด"
มันจะช่วยให้ต้องจัดการกฎซ่อน คุณสามารถอ่านเพิ่มเติมได้ที่นี่แต่ฉันจะพยายามอธิบายในไม่ช้า
ลองนึกภาพว่าฟังก์ชั่นเสมือนจริงของEngine
คลาสนั้นเป็นอินเทอร์เฟซและเป็นชุดของฟังก์ชั่นโอเวอร์โหลดที่ไม่ใช่เวอร์ชวลเพียว หากพวกเขาบริสุทธิ์เสมือนจริงหนึ่งยังคงประสบปัญหาเดียวกันตามที่อธิบายไว้ด้านล่าง แต่ลดลงในลำดับชั้นของชั้นเรียน
class Engine
{
public:
virtual void SetState( int var, bool val ) {/*some implementation*/}
virtual void SetState( int var, int val ) {/*some implementation*/}
};
ทีนี้สมมติว่าคุณต้องการสร้างคลาสที่ได้รับมาและคุณต้องเตรียมการนำไปใช้ใหม่สำหรับเมธอดเท่านั้นซึ่งจะใช้สอง ints เป็นอาร์กิวเมนต์
class MyTurbochargedV8 : public Engine
{
public:
// To prevent SetState( int var, bool val ) from the base class,
// from being hidden by the new implementation of the other overload (below),
// you have to put using declaration in the derived class
using Engine::SetState;
void SetState( int var, int val ) {/*new implementation*/}
};
หากคุณลืมใส่การประกาศโดยใช้ในคลาสที่ได้รับ (หรือเพื่อกำหนดโอเวอร์โหลดที่สองอีกครั้ง) คุณอาจประสบปัญหาในสถานการณ์ด้านล่าง
MyTurbochargedV8* myV8 = new MyTurbochargedV8();
myV8->SetState(5, true);
หากคุณไม่ได้ป้องกันการซ่อนEngine
สมาชิกข้อความ:
myV8->SetState(5, true);
จะเรียกvoid SetState( int var, int val )
จากชั้นเรียนมาแปลงไปtrue
int
หากอินเทอร์เฟซไม่เสมือนและการใช้งานเสมือนจริงไม่เป็นสาธารณะเช่นใน exmaple ของคุณผู้เขียนของคลาสที่ได้รับมีปัญหาน้อยกว่าหนึ่งคิดและสามารถเขียน
class MyTurbochargedV8 : public Engine
{
private:
void SetStateInt(int var, int val ) {/*new implementation*/}
};