Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Шаблонные классы коллекций MFC
Ниже рассматриваются типо-безопасные шаблонные классы коллекций MFC версий 3.0 и более поздних. Использование этих шаблонных классов для создания типо-безопасных коллекций является более удобным и надежным по сравнению с использованием нешаблонных классов. MFC предоставляет две категории шаблонных коллекций: · простые массивы CArray, списки CList и ассоциативные массивы CMap; · массивы CTypedPtrArray, списки CTypedPtrList и ассоциативные массивы типизированных указателей CTypedPtrMap.
Так как все эти коллекции производны от класса CObject, то все они, как правило, наследуют сериализацию, динамическое создание и другие свойства CObject. Классы коллекций типизированных указателей требуют указать в качестве родительского класса какую-либо нешаблонную коллекцию указателей, например, CPtrList или CPtrArray. Ваш новый класс коллекции является наследником указанного базового класса и его член-функции используют вызовы функций базового класса для усиления типо-безопасности.
Использование массивов, списков и ассоциативных массивов Использование простых массивов и списков Шаблонные классы CArray и CList имеют два параметра: TYPE и ARG_TYPE. Эти классы могут сохранять данные любого типа, который Вы должны указать в качестве параметра TYPE: фундаментальные (основные) типы, такие как int, char, float и т.д.; структуры и классы С++; другие пользовательские типы.
Классы CArray и CList объявлены в файле Afxtempl.h так: template<class TYPE, class ARG_TYPE> class CArray : public CObject {…};
template<class TYPE, class ARG_TYPE> class CList : public CObject { protected: struct CNode { CNode* pNext; CNode* pPrev; TYPE data; }; {…};
Для удобства и эффективности Вы можете использовать параметр ARG_TYPE для определения типа аргументов функций. Обычно в качестве ARG_TYPE указывают ссылку на тип TYPE. Например: #include <Afxtempl.h> … CArray<int, int> myArray; CList<CPerson, CPerson&> myList;
Класс myArray представляет собой массив целых чисел, а myList – список классов CPerson.
Члены класса CArray В приведенной ниже таблице представлены члены класса CArray, а ниже дано их более полное описание. Ключевым моментом класса является возможность индексирования элементов массива целым числом от 0 до N-1, где N – число элементов массива. При обращении к элементам массива по индексу, например, с помощью перегруженной операции [], недопустимо обращаться к несуществующим элементам, так как автоматического расширения размера массива в этом случае не происходит. Вместе с тем автоматическое расширение массива происходит при использование функций Add(), SetAtGrow(), Append(), Copy().
Таблица 1 Члены класса CArray
Конструкторы CArray() Создает пустой массив.
Атрибуты int GetSize() const; Возвращает фактическое число элементов массива.
int GetUpperBound() const; Возвращает максимальный допустимый индекс (на единицу меньше GetSize()).
void SetSize(int nNewSize, int nGrowBy =-1); throw(CMemoryException ); Задает число элементов массива. nNewSize – новое число элементов массива; nGrowBy – минимальное число элементов, на которое увеличивается размер массива в случае необходимости. Если nGrowBy ==-1, то MFC сама оптимизирует распределение памяти.
Примечания. Задает размер нового или существующего массива. Если новый размер меньше текущего, то массив усекается и вся неиспользуемая память освобождается. Эту функцию нужно использовать для задания размера массива перед его использованием. Если Вы ее не используете, то включение элементов в массив с помощью Add() вызывает постоянное перераспределение памяти, что вызывает ее неэффективное использование и фрагментирование. Обработка void FreeExtra( ); Освобождает всю неиспользуемую память за верхним индексом массива. Функция не влияет на число элементов массива.
void RemoveAll( ); Удаляет все элементы массива. Может применяться к пустому массиву.
Доступ к элементам TYPE GetAt( int nIndex ) const; Возвращает значение с указанным индексом. Попытка извлечения несуществующего элемента вызовет ошибку.
void SetAt( int nIndex, ARG_TYPE newElement ); Присваивание нового значения newElement элементу массива с номером nIndex. Использование этой функции не вызывает автоматического увеличения размера массива – используйте для этого SetAtGrow().
TYPE& ElementAt( int nIndex ); Возвращает временную ссылку на элемент с номером nIndex. Она используется для перегрузки оператора присваивания.
const TYPE* GetData( ) const; TYPE* GetData( ); Разрешает непосредственный доступ к элементам массива, возвращая указатель на массив. Хотя прямой доступ к элементам и эффективен, такой подход чреват ошибками.
Увеличение размера массива void SetAtGrow(intnIndex,ARG_TYPE newElement); throw(CMemoryException); Присваивание нового значения newElement элементу массива с номером nIndex. Использование этой функции вызывает, при необходимости, автоматическое увеличение размера массива. int Add( ARG_TYPE newElement ); throw( CMemoryException ); Добавляет новый элемент в конец массива. Использование этой функции вызывает, при необходимости, автоматическое увеличение размера массива. int Append( const CArray & src ); Добавляет массив src к существующему и возвращает индекс первого добавленного элемента. Использование этой функции вызывает, при необходимости, автоматическое увеличение размера массива. void Copy( const CArray & src ); Копирует массив src в существующий. При необходимости увеличивает память для текущего массива. Новый массив заменяет существующий. Функция не совобождает память, если таковая появляется.
Вставки и удаления void InsertAt( int nIndex, ARG_TYPE newElement, int nCount = 1 ); void InsertAt( int nStartIndex, CArray* pNewArray ); throw( CMemoryException ); Вставляет новый элемент newElement в позицию массива с номером nIndex или все элементы массива pNewArray. Первая функция вставляет один элемент или nCount копий элемента в указанную позицию массива, а вторая перегруженная версия функции вставляет массив. При вставке все «правые» элементы массива сдвигаются. Операции TYPE& operator []( int nIndex ); TYPE operator []( int nIndex ) const; Получает или устанавливает значение элемента массива с номером nIndex. Эта операция является удобным заменителем функций SetAt() и GetAt(). В отладочной версии программы возникает ошибка (failed assert) при попытке при попытке обращения к несуществующему элементу массива.
Члены класса CList Замечание ко всем функциям списка. Тип POSITION не является номером элемента в списке или его индексом и Вы не должны пытаться его модифицировать как обычную переменную. Получайте значение позиции элемента с помощью функций GetHeadPosition(), GetTailPosition(), Find() или FindIndex().
Конструктор CList( int nBlockSize = 10 ); Создает пустой список. Параметр nBlockSize задает гранулярность списка, т.е. число элементов списка, на которое он будет увеличиваться при расширении.
Функция GetHead() Возвращает головной элемент или ссылку на него. TYPE& GetHead( );TYPE GetHead( ) const;
Возвращаемое значение Если список неконстантный, то возвращаемая функцией ссылка может быть использована в левой части оператора присваивания. Замечания Функция должна вызываться для непустого списка.
Функция GetTail() Возвращает хвостовой элемент или ссылку на него. TYPE& GetTail( );TYPE GetTail() const;Возвращаемое значение Если список неконстантный, то возвращаемая функцией ссылка может быть использована в левой части оператора присваивания. Замечания Функция должна вызываться для непустого списка.
Функция RemoveHead() Удаляет головной элемент и возвращает его значение или ссылку на него. TYPE RemoveHead();Пример: CList <double, double> list; double dbl; list.AddTail(1.1); list.AddTail(2.2); dbl=list.RemoveHead(); cout<<"list.RemoveHead() "<<dbl<<endl; // выводит 1.1
CList <double, double&> listref; dbl=1.1; listref.AddTail(dbl); dbl=2.2; listref.AddTail(dbl); listref.GetHead()=0.1; dbl=listref.RemoveHead(); cout<<"listref.RemoveHead() "<<dbl<<endl; // выводит 0.1
Функция RemoveTail() Удаляет хвостовой элемент и возвращает его значение или ссылку на него. TYPE RemoveTail();Замечания Эта функция подобна RemoveHead() – см. пример для нее.
Функция AddHead() Добавляет элемент или все элементы другого списка в голову данного. POSITION AddHead( ARG_TYPE newElement );void AddHead(CList* pNewList);Параметры newElement Значение нового элемента списка. pNewList Указатель на вставляемый список, элементы которого будут вставлены в голову данного списка.
Функция AddTail() Добавляет элемент или все элементы другого списка в голову данного. POSITION AddTail(ARG_TYPE newElement );void AddTail(CList* pNewList);Параметры newElement Значение нового элемента списка. pNewList Указатель на вставляемый список, элементы которого будут добавлены к данному списку.
Функция RemoveAll() Удаляет все элементы списка и освобождает выделенную для него память. Список может быть пустым. void RemoveAll();
Функция GetHeadPosition() Возвращает позицию головного элемента списка. POSITION GetHeadPosition() const;Возвращаемое значение Возвращаемое значение может быть использовано для итераций или поиска указателя. Функция возвращает NULL для пустого списка.
Функция GetTailPosition() Возвращает позицию хвостового элемента списка. POSITION GetTailPosition() const;Возвращаемое значение Возвращаемое значение может быть использовано для итераций или поиска указателя. Функция возвращает NULL для пустого списка.
Функция GetNext() Возвращает значение элемента с указанной позицией и модифицирует позицию так, чтобы она указывала на следующий элемент списка. TYPE & GetNext( POSITION & rPosition );TYPE GetNext( POSITION & rPosition ) const;
Параметр rPosition Ссылка на позицию, возвращенная предыдущим вызовом этой функции или какой-либо другой. Возвращаемое значение Значение элемента с указанной позицией или ссылку на него. Замечания Эту функцию можно использовать в цикле, получив первоначальное значение позиции с помощью GetHeadPosition() или Find(). Если полученный элемент является последним в списке, то rPosition==NULL, что и нужно проверять во избежание ошибки.
Функция GetPrev() Возвращает значение элемента с указанной позицией и модифицирует позицию так, чтобы она указывала на предыдущий элемент списка. TYPE & GetPrev ( POSITION & rPosition );TYPE GetPrev ( POSITION & rPosition ) const;
Данная функция подобна GetNext(), описание которой приведено выше.
Иллюстрация функций, предназначенных для выполнения итераций (проект AlgTest): CList <int,int&>list; POSITION pos; for(int i=0;i<5;i++) list.AddTail(i); pos=list.GetHeadPosition(); while(pos) cout<<list.GetNext(pos)<<' '; // выводит 0 1 2 3 4 cout<<endl; pos=list.GetTailPosition(); while(pos) list.GetPrev(pos)*=2; pos=list.GetHeadPosition(); while(pos) cout<<list.GetNext (pos)<<' '; // выводит 0 2 4 6 8
Функция GetAt() Возвращает элемент с позицией position или ссылку на него. TYPE & GetAt( POSITION position );TYPE GetAt( POSITION position ) const;Параметры position Позиция элемента списка, значение которого надо получить. Возвращаемое значение Значение элемента или ссылка на него. Замечания Убедитесь в том, что значение position корректно.
Функция SetAt() Устанавливает новое значение newElement элемента списка с позицией pos. void SetAt( POSITION pos, ARG_TYPE newElement);Параметры pos Позиция элемента списка, значение которого надо установить. Замечания Убедитесь в том, что значение pos корректно.
Функция RemoveAt() Удаляет элемент с заданной позицией pos. void RemoveAt( POSITION pos);Параметры pos Позиция элемента списка, значение которого надо удалить. Замечания Убедитесь в том, что значение pos корректно.
Функция InsertBefore() Вставляет в список новый элемент со значением newElement в позицию перед заданной значением параметра position. POSITION InsertBefore( POSITION position, ARG_TYPE newElement );Параметры position Позиция элемента списка, перед котором надо вставить новый элемент.
newElement Значение вставляемого элемента списка. Возвращаемое значение Позиция вставленного элемента списка, которая может быть использована в цикле. Замечания Убедитесь в том, что значение pos корректно.
Функция InsertAfter() Вставляет в список новый элемент со значением newElement в позицию после заданной значением параметра position. POSITION InsertAfter( POSITION position, ARG_TYPE newElement );
Функция подобна InsertBefore(), описанной выше.
Функция Find() Последовательно просматривает список для нахождения элемента, соответствующего заданному параметром searchValue, и возвращает его позицию – значение типа POSITION. POSITION Find( ARG_TYPE searchValue, POSITION startAfter = NULL) const;Параметры searchValue Искомое значение. Возвращаемое значение Позиция элемента или NULL.. Замечания При поиске элемента сравниваются значения типа ARG_TYPE, которые могут оказаться и указателями, в зависимости от объявления класса. Например, в следующем фрагменте программы будет найдено и выведено вещественное значение 50., если оно есть в списке: CList <double,double&> Vec; double Val; // заполнение списка вещественными числами Val=50.; POSITION pos=Vec.Find(Val); if (pos) cout<<Vec.GetAt(pos)<<endl;
Функция FindIndex() Последовательно просматривает список для нахождения элемента с последовательным номером nIndex (начинающимся с нуля) и возвращает его позицию – значение типа POSITION. POSITION FindIndex( int nIndex ) const;Параметры nIndex Искомый номер элемента списка. Возвращаемое значение Позиция элемента или NULL..
Пример программы: CList <int,int&> list; POSITION pos; for(int i=0;i<5;i++) { int work=i*10; list.AddTail(work); } pos=list.FindIndex(3); if(pos) cout<<'\n'<<list.GetAt(pos)<<endl; // выводит 30
Отметим, что, казалось бы, оператор list.AddTail(i*10); тоже можно было бы написать. Однако, такой оператор вызовет сообщение компилятора об ошибке. В чем же проблема? Да в том, что второй параметр шаблона списка мы объявили ссылкой (первая строка фрагмента программы) и, следовательно, фактический параметр функции AddTail() должен быть обязательно переменной, а не выражением.
Функция GetCount() Возвращает количество элементов списка. int GetCount() const;
Функция IsEmpty() Возвращает значение TRUE, если список пустой. BOOL IsEmpty( ) const;
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 636. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |