указатель на метод базового класса и права доступа
От: biomorph Россия  
Дата: 17.10.06 10:12
Оценка:
Всем привет.

Данный вопрос уже пару раз обсуждался, но ясного ответа почему так происходит не было.

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). Такое поведение мне не понятно и кажется не логичным.

Почему же нельзя взять адрес, чем это продиктовано? Если можно с ссылками на стандарт.

Спасибо
Re: указатель на метод базового класса и права доступа
От: Greg Zubankov СССР  
Дата: 17.10.06 10:36
Оценка: 16 (3)
Здравствуйте, 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
    };
Re[2]: указатель на метод базового класса и права доступа
От: biomorph Россия  
Дата: 17.10.06 12:44
Оценка:
Здравствуйте, Greg Zubankov, Вы писали:

GZ>11.5/1 Protected member access


Спасибо за ссылку.

Жаль, что стандарт ничего не говорит о природе этого явления. Но по-моему, это не укладывается в правила контроля доступа. Получается, что при взятии адреса метода предка не учитываются привелегии наследника, но учитываются привелегии друзей.
Как-то логически можно объяснить этот пункт или его просто надо запомнить?
Re[3]: указатель на метод базового класса и права доступа
От: VoidEx  
Дата: 17.10.06 13:59
Оценка: 3 (2)
Здравствуйте, 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 функцию другого объекта, а это запрещено.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.