В первом случае вы берете адрес указателя на член B::b
.Поскольку такой указатель НЕ является членом родительского элемента A
, а является отдельным объектом, он не может получить к нему доступ через защищенный механизм.
В ВТОРОМ случае, когда он работает, вы запрашиваетеадрес конкретного экземпляра из b
с указанием его базового класса, чтобы в случае множественного наследования компилятор знал, какой базовый класс вы имеете в виду.В этом контексте защищенный атрибут виден.
Обратите внимание, что это компилируется:
class B
{
protected:
int b;
};
class A : public B
{
public:
void foo(){ &A::b; } // Note here &A:: instead of &B::
};
В качестве дополнительного примера он не работает по той же причине, что и следующая (надеюсь, более знакомая)код не работает:
class B
{
protected:
int b;
};
class A : public B
{
public:
void foo(const B* b_obj) { b_obj->b; }
};