Несмотря на все призывы объявить виртуального члена приватным, аргумент просто не выдерживает критики. Часто переопределение производного класса виртуальной функции должно вызывать версию базового класса. Не может, если объявлено 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 */ }
...
Таким образом, рекомендация Херба Саттера №3 ... Но лошадь все равно вышла из сарая.
Когда вы объявляете что-то protected
, вы неявно доверяете создателю любого производного класса понимать и правильно использовать защищенные внутренние компоненты, точно так же, как объявление friend
подразумевает более глубокое доверие для private
членов.
Пользователи, у которых плохое поведение нарушает это доверие (например, помечены как «невежественные», не удосужившись прочитать вашу документацию), сами виноваты.
Обновление : я получил несколько отзывов, в которых утверждается, что вы можете «цеплять» реализации виртуальных функций таким образом, используя частные виртуальные функции. Если так, то я бы очень хотел это увидеть.
Компиляторы C ++, которые я использую, определенно не позволят реализации производного класса вызывать реализацию частного базового класса.
Если бы комитет C ++ ослабил «приватность», чтобы разрешить этот конкретный доступ, я бы все для приватных виртуальных функций. Пока он стоит, нам все еще советуют запирать дверь сарая после того, как лошадь украдена.