#ооп #наследование #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 и все такое :)
Комментариев нет:
Отправить комментарий