แม้จะมีการเรียกร้องให้ประกาศความเป็นส่วนตัวของสมาชิกเสมือน แต่ข้อโต้แย้งก็ไม่ถือน้ำ บ่อยครั้งการแทนที่คลาสที่ได้รับมาของฟังก์ชันเสมือนจะต้องเรียกใช้เวอร์ชันคลาสพื้นฐาน ไม่สามารถทำได้หากมีการประกาศprivate
:
class Base
{
private:
int m_data;
virtual void cleanup() { /*do something*/ }
protected:
Base(int idata): m_data (idata) {}
public:
int data() const { return m_data; }
void set_data (int ndata) { m_data = ndata; cleanup(); }
};
class Derived: public Base
{
private:
void cleanup() override
{
// do other stuff
Base::cleanup(); // nope, can't do it
}
public:
Derived (int idata): base(idata) {}
};
คุณมีprotected
การประกาศวิธีการเรียนฐาน
จากนั้นคุณต้องใช้ความสะดวกที่น่าเกลียดในการระบุผ่านความคิดเห็นว่าวิธีนี้ควรถูกแทนที่ แต่ไม่เรียก
class Base
{
...
protected:
// chained virtual function!
// call in your derived version but nowhere else.
// Use set_data instead
virtual void cleanup() { /* do something */ }
...
ดังนั้นแนวทางของ Herb Sutter # 3 ... แต่ม้าก็ออกจากโรงนาอยู่ดี
เมื่อคุณประกาศบางสิ่งprotected
คุณโดยปริยายไว้วางใจให้นักเขียนของชั้นเรียนที่ได้รับมาเข้าใจและใช้งานภายในที่ได้รับการคุ้มครองอย่างถูกต้องวิธีการfriend
ประกาศนั้นบ่งบอกถึงความไว้วางใจที่ลึกซึ้งยิ่งขึ้นสำหรับprivate
สมาชิก
ผู้ใช้ที่ได้รับพฤติกรรมที่ไม่ดีจากการละเมิดความไว้วางใจนั้น (เช่นติดป้ายว่า 'ไม่เข้าใจ' โดยไม่รบกวนการอ่านเอกสารของคุณ) มี แต่จะตำหนิตัวเอง
อัปเดต : ฉันมีข้อเสนอแนะบางอย่างที่อ้างว่าคุณสามารถใช้ฟังก์ชันเสมือน "chain" ได้ด้วยวิธีนี้โดยใช้ฟังก์ชันเสมือนส่วนตัว ถ้าเป็นเช่นนั้นฉันอยากเห็น
คอมไพเลอร์ C ++ ที่ฉันใช้แน่นอนจะไม่ปล่อยให้การใช้งานคลาสที่ได้รับเรียกการใช้งานคลาสพื้นฐานส่วนตัว
หากคณะกรรมการ C ++ ผ่อนปรน "ส่วนตัว" เพื่ออนุญาตการเข้าถึงเฉพาะนี้ฉันจะใช้ฟังก์ชันเสมือนส่วนตัวทั้งหมด เรายังคงได้รับคำแนะนำให้ล็อกประตูโรงนาหลังจากที่ม้าถูกขโมยไป