Страницы

Поиск по вопросам

понедельник, 23 декабря 2019 г.

Доступ к protected методам родителя

#ооп #наследование #cpp


Я столкнулся с проблемой в C++, для которой не могу найти нормального решения.
Проблему иллюстрирует следующий пример:

class Parent {
 protected:
  int f() = 0;
};

class Child : public Parent {
 protected:
  int g(Parent& p) {
    return p.f(); // error: 'virtual int Parent::f()' is protected.
  }
  int g(Child& p) {
    return p.f(); // OK.
  }
};


Я хочу, чтобы метод f() был доступен только наследникам класса Parent. В реальной
задаче метод f() виртуальный и наследники его замещают (override), но сути проблемы
это не меняет.

Я знаю 2 плохих решения:


Сделать f() public. В данный момент его и использую. Этот решение плохое, потому
что я не хочу давать доступ к f() кому-либо, кроме наследников.
Добавить всех наследников в друзья родителя. Тут 2 минуса: private члены родителя
становятся доступны наследникам, и при добавлении нового наследника, мы становимся
обязаны обновить базовый класс.


Нашел похожий вопрос на SO, но там никого нормального решения так и не нашлось.
    


Ответы

Ответ 1



Как насчёт такого трюка: делегировать вызов f предку? (Проверка.) class Parent { protected: virtual int f() = 0; int CallFOn(Parent& p) { return p.f(); } }; class Child : public Parent { protected: int g(Parent& p) { return CallFOn(p); // OK. } int g(Child& p) { return p.f(); // OK. // или даже ( http://ideone.com/WLE27X ) // return CallFOn(p); } };

Ответ 2



Наверное легальным способом никак. В качестве более удобного решения можно реализовать дружественный класс-обертку и обращаться к приватным/защищенным методам через него. Думаю что плюсы очевидны: не нужно трогать базовый класс при добавлении дочерних, ну и можно менять реализацию в обертке не трогая дочерних классов, dependency injection и все такое :)

Комментариев нет:

Отправить комментарий