Всем привет.
Данный вопрос уже пару раз обсуждался, но ясного ответа почему так происходит не было.
class A
{
protected:
void funcA() {};
};
class B: public A
{
public:
void funcB()
{
B::funcA(); // ok
A::funcA(); // ok
&A::funcA; // error
};
};
Адрес A::funcA взять нельзя, несмотря на то, что класс B имеет все полномочия для доступа к методу. Если объявить В другом, то ошибки не будет (т.е. права появятся, хотя функция не private, а protected). Такое поведение мне не понятно и кажется не логичным.
Почему же нельзя взять адрес, чем это продиктовано? Если можно с ссылками на стандарт.
Спасибо
Здравствуйте, biomorph, Вы писали:
B>Почему же нельзя взять адрес, чем это продиктовано? Если можно с ссылками на стандарт.
B>Спасибо
11.5/1 Protected member access
When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5). If the access is to form a pointer to member, the nested-name-specifier shall name the derived class (or any class derived from that class).
Т.е. надо использовать так:
void funcB()
{
B::funcA(); // ok
A::funcA(); // ok
&B::funcA; // error
};
Здравствуйте, biomorph, Вы писали:
B>Здравствуйте, Greg Zubankov, Вы писали:
GZ>>11.5/1 Protected member access
B>Спасибо за ссылку.
B>Жаль, что стандарт ничего не говорит о природе этого явления. Но по-моему, это не укладывается в правила контроля доступа. Получается, что при взятии адреса метода предка не учитываются привелегии наследника, но учитываются привелегии друзей.
B>Как-то логически можно объяснить этот пункт или его просто надо запомнить?
Природа такова, что к protected членам есть доступ только к базовой составляющей самого this. А не к другому объекту.
Т.е.
class A { protected : int a; };
class B : public A {
void foo() { this->a = 23; } // ok
void foo2 (A * other) { other->a = 23; } // error!
}
Имея указатель на функцию базового класса, мы смогли бы вызвать protected функцию
другого объекта, а это запрещено.