|
Программирование >> Инициализация объектов класса, структура
(c) class iostream: private istream, private ostream { ... }; Упражнение 18.2 class A { ... }; class B : public A { ... }; class C : public B { ... }; class X { ... }; class Y { ... }; class Z : public X, public Y { ... }; Дана иерархия, в каждом классе которой определен конструктор но умолчанию: class MI : public C, public Z { ... }; Каков порядок вызова конструкторов в таком определении: MI mi; Упражнение 18.3 class X { ... }; class A { ... }; class B : public A { ... }; class C : private B { ... }; Дана иерархия, в каждом классе которой определен конструктор по умолчанию: class D : public X, public C { ... }; Какие из следующих преобразований недопустимы: D *pd = new D; (a) X *px = pd; (c) B *pb = pd; (b) A *pa = pd; (d) C *pc = pd; Упражнение 18.4 Дана иерархия классов, обладающая приведенным ниже набором виртуальных функций: class Base { public: virtual ~Base(); virtual ostreamS print(); virtual void debug(); virtual void readOn(); virtual void writeOn(); ... class Derived1 : virtual public Base { public: virtual ~Derived1(); virtual void writeOn(); ... class Derived2 : virtual public Base { public: virtual ~Derived2(); virtual void readOn(); ... class MI : public Derived1, public Derived2 { public: virtual ~MI(); virtual ostreamS print(); virtual void debug(); Base *pb = new MI; (a) pb->print(); (c) pb->readOn(); (e) pb->log(); Какой экземпляр виртуальной функции вызывается в каждом из следующих случаев: (b) pb->debug(); (d) pb->writeOn(); (f) delete pb; Упражнение 18.5 На примере иерархии классов из упражнения 18.4 определите, какие виртуальные функции активны при вызове через pd1 и pd2: (b) MI obj; (a) Derived1 *pd1 new MI; Derived2 d2 = obj; bool PeekbackStack:: который поддерживает выборку из стека с помощью метода peekback() : peekback( int index, type Svalue ) { ... } где value содержит элемент в позиции index, если peekback() вернула true. Если же peekback() возвращает false, то заданная аргументом index позиция некорректна и в value помещается элемент из вершины стека. В реализации PeekbackStack возможны два типа ошибок: реализация абстракции PeekbackStack: некорректная реализация поведения класса; реализация представления данных: неправильное управление выделением и освобождением памяти, копированием объектов из стека и т. п. Обычно стек реализуется либо как массив, либо как связанный список элементов (в стандартной библиотеке по умолчанию это делается на базе двусторонней очереди, хотя вместо нее можно использовать вектор, см. главу 6). Хотелось бы иметь гарантированно правильную (или, по крайней мере, хорошо протестированную и поддерживаемую) реализацию массива или списка, чтобы использовать ее в нашем классе PeekbackStack. Если она есть, то можно сосредоточиться на правильности поведения стека. У нас есть класс IntArray, представленный в разделе 2.3 (mi временно откажемся от применения класса deque из стандартной библиотеки и от поддержки элементов, имеющих отличный от int тип). Вопрос, таким образом, заключается в том, как лучше всего воспользоваться классом IntArray в нашей реализации PeekbackStack. Можно задействовать механизм наследования. (Отметим, что для этого нам придется модифицировать IntArray, сделав его члены защищенными, а не закрытыми.) Реализация в1глядела бы так: 18.3. Открытое, закрытое и защищенное наследование Открытое наследование называется еще наследованием типа. Производный класс в этом случае является подтипом базового; он замещает реализации всех функций-членов, специфичных для типа базового класса, и наследует общие для типа и подтипа функции. Можно сказать, что производный класс служит примером отношения ЯВЛЯЕТСЯ , т.е. предоставляет специализацию более общего базового класса. Медведь (Bear) является животным из зоопарка (ZooAnimal); аудиокнига (AudioBook) является предметом, выдаваем1м читателям (LibraryLendingMaterial). М1 говорим, что Bear - это подтип ZooAnimal, равно как и Panda. Аналогично AudioBook - подтип LibBook (библиотечная книга), а оба они - подтипы LibraryLendingMaterial. В любом месте программы, где ожидается базовый тип, можно вместо него подставить открыто унаследованный от него подтип, и программа будет продолжать работать правильно (при условии, конечно, что подтип реализован корректно). Во всех приведенных выше примерах демонстрировалось именно наследование типа. Закрытое наследование называют также наследованием реализации. Производн1й класс напрямую не поддерживает открытый интерфейс базового, но пользуется его реализацией, предоставляя свой собственный открытый интерфейс. Чтобы показать, какие здесь возникают вопросы, реализуем класс PeekbackStack,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |