เท่าที่ฉันเข้าใจการแนะนำของoverride
คำหลักใน C ++ 11 ไม่มีอะไรมากไปกว่าการตรวจสอบเพื่อให้แน่ใจว่าฟังก์ชั่นการใช้งานเป็นการนำoverride
ของvirtual
ฟังก์ชั่นในชั้นฐาน
มันคืออะไร
เท่าที่ฉันเข้าใจการแนะนำของoverride
คำหลักใน C ++ 11 ไม่มีอะไรมากไปกว่าการตรวจสอบเพื่อให้แน่ใจว่าฟังก์ชั่นการใช้งานเป็นการนำoverride
ของvirtual
ฟังก์ชั่นในชั้นฐาน
มันคืออะไร
คำตอบ:
นั่นเป็นความคิดที่แน่นอน ประเด็นก็คือคุณมีความชัดเจนเกี่ยวกับสิ่งที่คุณหมายถึงเพื่อให้สามารถวินิจฉัยข้อผิดพลาดแบบเงียบได้:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
โค้ดข้างต้นรวบรวม แต่ไม่ใช่สิ่งที่คุณอาจหมายถึง (หมายเหตุที่ขาดหายไปconst
) หากคุณพูดแทนคุณvirtual int foo() override
จะได้รับข้อผิดพลาดของคอมไพเลอร์ซึ่งฟังก์ชั่นของคุณไม่ได้อยู่เหนือความจริง
override
คุณสมบัติใหม่นี้ "แก้ไข" สิ่งนี้; คุณต้องจำไว้ว่าให้ใช้มันอย่างที่ควรจำไว้เพื่อเขียนconst
;)
explicit
คำจำกัดความของคลาสไม่ได้ทำให้เป็น C ++ 11 ฮะ.
explicit
นิยามของคลาสจะทำอย่างไร ไม่เคยได้ยินเรื่องนี้เลย
override
เมื่อหนึ่งความตั้งใจที่จะทำมัน) คือจะมีโอกาสมากกว่าการจดจำกรณีมุมเช่นมีทั่วไปในการคัดลอกการทำงานของต้นแบบที่แตกต่างกันเพียงความผิดปกติเหมือนหายไปไม่มีconst
หรือเขียนchar
แทนint
ฯลฯ
คำพูดของ Wikipedia:
การแทนที่ตัวระบุพิเศษหมายความว่าคอมไพเลอร์จะตรวจสอบคลาสฐาน (es) เพื่อดูว่ามีฟังก์ชั่นเสมือนจริงที่มีลายเซ็นที่แน่นอนนี้ และหากไม่มีตัวแปลภาษาก็จะผิดพลาด
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
แก้ไข (พยายามปรับปรุงคำตอบเล็กน้อย):
การประกาศเมธอดเป็น "override" หมายความว่าเมธอดนั้นมีจุดประสงค์เพื่อเขียนเมธอด (เสมือน) บนคลาสพื้นฐาน วิธีการเอาชนะต้องมีลายเซ็นเดียวกัน (อย่างน้อยสำหรับพารามิเตอร์อินพุต) เป็นวิธีที่มันตั้งใจที่จะเขียนใหม่
ทำไมถึงจำเป็น กรณีข้อผิดพลาดทั่วไปสองกรณีต่อไปนี้ได้รับการป้องกัน:
หนึ่งพิมพ์ผิดในวิธีการใหม่ คอมไพเลอร์ไม่ทราบว่ามีความตั้งใจที่จะเขียนวิธีการก่อนหน้าเพียงแค่เพิ่มวิธีนี้ลงในคลาสเป็นวิธีการใหม่ ปัญหาคือว่าวิธีการเดิมยังคงอยู่ที่นั่นวิธีการใหม่จะถูกเพิ่มเป็นโอเวอร์โหลด ในกรณีนี้การเรียกไปยังเมธอดเก่าทั้งหมดจะทำงานเหมือนเมื่อก่อนโดยไม่มีการเปลี่ยนแปลงในพฤติกรรม (ซึ่งจะเป็นจุดประสงค์ของการเขียนใหม่)
หนึ่งลืมที่จะประกาศวิธีการในซูเปอร์คลาสเป็น "เสมือน" แต่ยังคงพยายามที่จะเขียนมันใหม่ในคลาสย่อย ในขณะที่สิ่งนี้จะได้รับการยอมรับพฤติกรรมจะไม่ตรงตามที่ตั้งใจไว้: วิธีการนี้ไม่ได้เป็นเสมือนจริงดังนั้นการเข้าถึงผ่านพอยน์เตอร์ไปยังซูเปอร์คลาสจะสิ้นสุดการเรียกเมธอดเก่า (superclass ') แทนวิธีการใหม่
การเพิ่ม "การแทนที่" อย่างชัดเจนทำให้ disambiguates สิ่งนี้: ผ่านสิ่งนี้สิ่งหนึ่งกำลังบอกคอมไพเลอร์ว่ามีสามสิ่งที่คาดหวัง:
หากสิ่งเหล่านี้เป็นเท็จแสดงว่ามีข้อผิดพลาด
* หมายเหตุ: บางครั้งพารามิเตอร์เอาท์พุทจะแตกต่างกัน แต่เป็นประเภทที่เกี่ยวข้อง อ่านเกี่ยวกับการแปรปรวนร่วมและการแปรเปลี่ยนหากสนใจ
พบว่า "การแทนที่ " มีประโยชน์เมื่อมีคนอัปเดตลายเซ็นเมธอดเสมือนคลาสพื้นฐานเช่นการเพิ่มพารามิเตอร์ทางเลือก แต่ลืมที่จะอัพเดตลายเซ็นเมธอดคลาสที่ได้รับ ในกรณีนั้นวิธีการระหว่างฐานและคลาสที่ได้รับจะไม่มีความสัมพันธ์แบบ polymorphic อีกต่อไป หากไม่มีการประกาศแทนที่มันเป็นการยากที่จะหาข้อผิดพลาดชนิดนี้
override
เป็นวิธีที่ดีในการค้นพบปัญหาดังกล่าวหน่วยทดสอบครอบคลุมที่ดีก็ควรช่วย
ใช่มันเป็นเช่นนั้น เป็นการตรวจสอบเพื่อให้แน่ใจว่าไม่ได้ลองแทนที่และทำมันผ่านลายเซ็นที่เรียบร้อย นี่คือหน้าวิกิที่อธิบายรายละเอียดนี้และมีตัวอย่างสั้น ๆ :
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
ร่างมาตรฐาน C ++ 17
หลังจากไปดูoverride
เพลงฮิตทั้งหมดในร่างมาตรฐาน C ++ 17 N4659การอ้างอิงเดียวที่ฉันสามารถหาoverride
ตัวระบุได้คือ:
5 หากฟังก์ชันเสมือนถูกทำเครื่องหมายด้วยการแทนที่ virt-specifier และไม่แทนที่ฟังก์ชันสมาชิกของคลาสพื้นฐานโปรแกรมจะถูกจัดรูปแบบไม่ถูกต้อง [ตัวอย่าง:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- ตัวอย่างท้าย]
ดังนั้นฉันคิดว่าการระเบิดโปรแกรมที่ไม่ถูกต้องอาจเป็นผลกระทบเดียว