|
Программирование >> Инициализация объектов класса, структура
template <class elemType> class list { public: list() : at front( 0 ), at end( 0 ), current( 0 ), size( 0 ) {} 1ist( const lists ) ; lists operator=( const lists ); ~list() { remove all(); } void insert ( list item<elemType> *ptr, elemType value ); void insert end( elemType value ); void insert front( elemType value ); void insert all( const list srhs ); int remove( elemType value ); void remove front(); void remove all(); list item<elemType> *find( elemType value ); list item<elemType> *next iter(); list item<elemType>* init iter( list item<elemType> *it ); void disp1ay( ostream sos = cout ); void concat( const lists ); void reverse (); int size() { return size; } private: void bump up size() { ++ size; } void bump down size() { -- size; } list item<elemType> * at front; 1ist item<elemType> * at end; list item<elemType> * current; int size; Объекты шаблона класса list используются точно так же, как и объекты класса ilist. Основное преимущество шаблона в том, что он обеспечивает поддержку произвольных типов данных с помощью единственного определения. (Шаблоны являются важной составной частью концепции программирования на С++. В главе 6 м1 рассмотрим набор классов контейнерных типов, нредоставляем1х стандартной библиотекой С++. Неудивительно, что она содержит шаблон класса, реализующего операции со списками, равно как и шаблон класса, поддерживающего векторы; м1 рассматривали их в главах 2 и 3.) Наличие класса списка в стандартной библиотеке представляет некоторую проблему. Мы выбрали для нашей реализации название list, но, к сожалению, стандартный класс также носит это название. Теперь мы не можем использовать в программе одновременно оба класса. Конечно, проблему решит переименование нашего шаблона, однако во многих случаях эта возможность отсутствует. Более общее решение состоит в использовании механизма пространства имен, который позволяет разработчику библиотеки заключить все свои имена в некоторое поименованное пространство и таким образом избежать конфликта с именами из глобального пространства. Применяя нотацию квалифицированного доступа, мы можем наш заголовочн файл #include list.h сделаем наши определения видими в программе using namespace Primer Third Edition; теперь можно использовать наш класс list list< int > ilist; следующее: ... (Пространства имен описываются в разделах 8.5 и 8.6.) Упражнение 5.16 Мы не определили деструктор для ilist item, хотя класс содержит указатель на динамическую область памяти. Причина заключается в том, что класс не выделяет память для объекта, адресуемого указателем next, и, следовательно, не несет ответственности за ее освобождение. Начинающий программист мог бы допустить ilist item::~ilist item() delete next; ошибку, вызвав деструктор для ilist item: Посмотрите на функции remove all() и remove front() и объясните, почему наличие такого деструктора является ошибочным. Упражнение 5.17 void ilist::remove end(); Наш класс ilist не поддерживает следующие операции: употреблять эти имена в программах. Стандартная библиотека С++ помещает свои имена namespace Primer Third Edition { template <typename elemType> class list item{ ... }; template <typename elemType> class list{ ... }; ... в пространство std. Мы тоже поместим наш код в собственное пространство: Для использования такого класса в пользовательской программе необходимо написать class ilist { public: public: ... ilist item* find( int value, ilist item *start at = 0 ); ... использующие предыдущую версию find() , будут работать без модификации.) Упражнение 5.19 Используя новую версию find() , напишите функцию count() , которая подсчитывает количество вхождений элементов с заданным значением. Подготовьте тестовую программу. Упражнение 5.20 Модифицируйте insert(int value) так, чтобы она возвращала указатель на вставленный объект ilist item. Упражнение 5.21 void ilist:: insert( ilist item *begin, int *array of value, Используя модифицированную версию insert() , напишите функцию: int elem cnt ); где array of value указывает на массив значений, который нужно вставить в ilist, elem cnt - на размер этого массива, а begin - на элемент, после которого производится вставка. Например, если есть ilist: i (3)( 0 1 21 ) и массив: int ia[] = { 1, 2, 3, 5, 8, 13 }; вызов этой новой функции void ilist::remove( ilist item* ); Как вы думаете, почему мы их не включили? Реализуйте их. Упражнение 5.18 Модифицируйте функцию find() так, чтобы вторым параметром она принимала адрес элемента, с которого нужно начинать поиск. Если этот параметр не задан, поиск начинается с первого элемента. (Поскольку мы добавляем второй параметр, имеющий значение по умолчанию, открытый интерфейс данной функции не меняется. Программы,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |