Примечание. Прямой (и рекомендуемый) способ включить что-либо, поскольку это сделать унаследованный класс friend базового класса; это означает, что он будет иметь доступ к своим protected и private частям.
Я хочу немного изменить правила
Итак, вы решили, что правила, установленные Стандартом, раздражают, вы хотите делать все, что хотите, когда хотите и так, как хотите! Правила созданы для того, чтобы их нарушать и т.д.
class B {
protected:
void f ();
};
<суп>суп>
class D : public B {
public:
void g (B * other) {
(other->*&D::f) (); // legal
}
};
Как работает этот легальный и полнофункциональный хак?
Несмотря на то, что Стандарт говорит, что нам не разрешено проверять B::f изнутри D, нам, конечно, разрешено смотреть на D::f; что то же самое (унаследовано), поскольку мы не объявляли еще один f внутри D.
Наш хак состоит в том, чтобы взять адрес D::f, полагаясь на тот факт, что его тип действительно является указателем на функцию-член внутри B, и использовать этот адрес для вызова функция на other.
Другой (семантически) эквивалентный способ написать фрагмент:
void (B::*hack)() = &D::f; (other->*hack) ();
Примечание. Технически мы не углубляемся в защищенное содержимое B, мы просто полагаемся на тот факт, что содержимое, доступ к которому осуществляется через D::f, оказывается таким же, как и в B::f. Мы по-прежнему играем по правилам, установленным Стандартом, просто немного нарушаем их.
person
Filip Roséen - refp
schedule
28.05.2014
friendзаключается в модульности.Bне нужно знать, какие классы будут его подклассами и будут использовать его защищенные функции. Это не совсем конкретный вопрос, потому что я знаю, что мог бы принять другой дизайн. Но в моем случае я не возражаю против вызова функций базового класса, подобных этому. - person Félix Faisant   schedule 28.05.2014