Хотя объект bulk имеет функцию-член discount_policy(), она недоступна через указатель itemP. Тип itemP — указатель на тип Quote, а это значит, что поиск имени discount_policy() начнется в классе Quote. У класса Quote нет члена по имени discount_policy(), поэтому вызов этой функции-члена объекта, ссылки или указателя на тип Quote невозможен.

Конфликт имен и наследование

Как и любая другая, область видимости производного класса позволяет повторно использовать имя, определенное в его прямом или косвенном базовом классе. Как обычно, имена, определенные во внутренней области видимости (например, в производном классе), скрывают имена во внешней области видимости (например, в базовом классе) (см. раздел 2.2.4):

struct Base {

 Base() : mem(0) { }

protected:

 int mem;

};

struct Derived : Base {

 Derived(int i): mem(i) { } // Derived::mem инициализируется i

                            // Base::mem инициализируется по умолчанию

 int get_mem() { return mem; } // возвращает Derived::mem

protected:

 int mem; // скрывает mem в Base

};

Ссылка на переменную mem в функции get_mem() распознается как имя в классе Derived. Таким образом, код

Derived d(42);

cout << d.get_mem() << endl; // выводит 42

выведет значение 42.

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

Применение оператора области видимости для доступа к скрытым членам

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

struct Derived : Base {

 int get_base_mem() { return Base::mem; }

};

Оператор области видимости изменяет нормальный порядок поиска и заставляет компилятор начинать поиск имени mem с класса Base. Если бы код выше был выполнен с этой версией класса Derived, то результатом вызова d.get_mem() был бы 0.

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

Перейти на страницу:

Похожие книги