bool
NameQuery::
compare( const Query *pquery )
{
// правильно: защищенный член подобъекта Query
int myMatches = _loc.size();
// ошибка: нет прав доступа к защищенному члену
// независимого объекта Query
int itsMatches = pquery->_loc.size();
return myMatches == itsMatches;
}
У объекта NameQuery есть доступ к защищенным членам только одного объекта Query – подобъекта самого себя. Прямое обращение к ним из производного класса осуществляется через неявный указатель this (см. раздел 13.4). Первая реакция на ошибку компиляции – переписать функцию compare() с использованием открытой функции-члена location():
bool
NameQuery::
compare( const Query *pquery )
{
// правильно: защищенный член подобъекта Query
int myMatches = _loc.size();
// правильно: используется открытый метод доступа
int itsMatches = pquery->locations()->size();
return myMatches == itsMatches;
}
Однако проблема заключается в неправильном проектировании. Поскольку _loc – это член базового класса Query, то место compare() среди членов базового, а не производного класса. Во многих случаях подобные проблемы могут быть решены путем переноса некоторой операции в тот класс, где находится недоступный член, как в приведенном примере.
Этот вид ограничения доступа не распространяется на доступ изнутри класса к другим объектам того же класса:
bool
NameQuery::
compare( const NameQuery *pname )
{
int myMatches = _loc.size(); // правильно
int itsMatches = name->_loc.size(); // тоже правильно
return myMatches == itsMatches;
}
Производный класс может напрямую обращаться к защищенным членам базового в других объектах того же класса, что и он сам, равно как и к защищенным и закрытым членам других объектов своего класса.
Рассмотрим инициализацию указателя на базовый Query адресом объекта производного NameQuery:
Query *pb = new NameQuery( "sprite" );
При вызове виртуальной функции, определенной в базовом классе Query, например: