Объект производного класса фактически построен из нескольких частей. Каждый базовый класс вносит свою долю в виде подобъекта, составленного из нестатических данных-членов этого класса. Объект производного класса построен из подобъектов, соответствующих каждому из его базовых, а также из части, включающей нестатические члены самого производного класса. Так, наш объект NameQuery состоит из подобъекта Query, содержащего члены _loc и _solution, и части, принадлежащей NameQuery,– она содержит только член _name.
Внутри производного класса к членам, унаследованным из базового, можно обращаться напрямую, как к его собственным. (Глубина цепочки наследования не увеличивает затраты времени и не лимитирует доступ к ним.) Например:
void
NameQuery::
display_partial_solution( ostream &os )
{
os << _name
<< " is found in "
<< (_solution ? _solution->size() : 0)
<< " lines of text\n";
}
Это касается и доступа к унаследованным функциям-членам базового класса: мы вызываем их так, как если бы они были членами производного – либо через его объект:
NameQuery nq( "Frost" );
// вызывается NameQuery::eval()
nq.eval();
// вызывается Query::display()
nq.display();
либо непосредственно из тела другой (или той же самой) функции-члена:
void
NameQuery::
match_count()
{
if ( ! _solution )
// вызывается Query::_vec2set()
_solution = _vec2set( &_loc );
return _solution->size();
}
Однако прямой доступ из производного класса к членам базового запрещен, если имя последнего скрыто в производном классе:
class Diffident {
public: // ...
protected:
int _mumble;
// ...
};
class Shy : public Diffident {
public: // ...
protected:
// имя Diffident::_mumble скрыто
string _mumble;
// ...
};
В области видимости Shy употребление неквалифицированного имени _mumble разрешается в пользу члена _mumble класса Shy (объекта string), даже если такое использование в данном контексте недопустимо: