Несмотря на все призывы объявить виртуальный член частным, аргумент просто не содержит воды. Часто переопределение производного класса виртуальной функции должно вызывать версию базового класса. Он не может, если он объявлен 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
членов.
Пользователи, которые плохого поведения нарушают это доверие (например, помечены как «невежественные», не утруждая себя чтением вашей документации), сами виноваты.
Обновление: У меня была некоторая обратная связь, в которой утверждается, что вы можете «объединить» реализации виртуальных функций таким образом, используя частные виртуальные функции. Если это так, я бы хотел это увидеть.
Компиляторы C++, которые я использую, определенно не позволят реализации производного класса вызвать реализацию частного базового класса.
Если комитет C++ расслабился «на частном», чтобы разрешить этот конкретный доступ, я был бы для частных виртуальных функций. В его нынешнем виде нам по-прежнему советуют запирать дверь сарая после того, как лошадь украдена.
Я думаю, что вопрос обратный. Причина создания чего-то виртуального всегда одинакова: позволить производным классам переопределять его. Поэтому вопрос должен быть: в чем преимущество частного виртуального метода? На что ответ: сделайте все закрытым по умолчанию. :-) – ShreevatsaR
@ShreevatsaR Но вы даже не ответили на свой вопрос ...... – Spencer