Доступ к защищенным элементам базового класса с помощью указателей на базовый класс в производном классе

Рассмотрим следующий код:

#include <iostream>

using std::endl;
using std::cout;

template<typename T>
class B{
protected:
T value;
B* ptr;
public:
B(T t):value(t), ptr(0){}
};

template<typename T>
class D: public B<T>{
public:
void f();
D(T t):B<T>(t){}
};

template<typename T>
void D<T>::f(){
cout << this->value << endl;     //OK!
this->ptr = this;
cout << this->ptr->value << endl;      //error! cannot access protected member!!
B<T>* a = this;
cout << a->value <<endl;       //error! cannot access protected member!!
}int main(){
D<double> a(1.2);
a.f();
return 0;
}

Кажется, что к члену базового класса можно напрямую получить доступ, используя this указатель, но не другие указатели.
Считает ли компилятор их различными экземплярами?

1

Решение

Да, это ожидаемое поведение. Защищенные участники базового класса можно получить в производном классе, но только через объект типа, который является производный класс (или дополнительный производный класс текущего производного класса) (включая this). Это означает, что вы не можете получить доступ к защищенным членам через указатель на базовый класс.

Доступ к защищенному члену класса Base возможен только

1) …

2) членами любого класса, производного от Base, но только когда
работающий с объектом типа, который является производным от Base (включая
этот)

4

Другие решения

Более простой пример теста:

class Base
{
protected:
int i;
};

class D1 : public Base
{
};

class D2 : public Base
{
int a(Base& b) { return b.i; } // error
int a(D1& d) { return d.i; }   // error

int a(D2& d) { return d.i; }
};

В производном классе D2мы можем получить доступ Base::i в D2 экземпляр, но не в Base экземпляр, ни в объекте, который является производным от Base не через D2,

В остальном хороший [C ++ Reference] [защищенный] говорит:

Защищенный член класса Base могут быть доступны […] членам любого класса, полученного из Base, но только при работе с объектом типа, который является производным от Base (в том числе this).

Приведенный выше тест предполагает, что формулировка там немного неточна — она ​​должна читаться «только при работе с объектом своего собственного типа или объекта, производного от него».


¹ или что GCC неверен — мы должны действительно проверить стандарт для этого.

0

По вопросам рекламы [email protected]