Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Шаблонные классы коллекций 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

CArray Создает пустой массив

Атрибуты класса CArray

GetSize Возвращает число элементов массива
GetUpperBound Возвращает максимальный допустимый индекс (на единицу меньше GetSize())
SetSize Задает число элементов массива

Обработка

FreeExtra Освобождает всю неиспользуемую память за верхним индексом массива
RemoveAll Удаляет все элементы массива

Доступ к элементам массива

GetAt Возвращает значение с указанным индексом
SetAt Присваивание нового значения элементу массива
ElementAt Возвращает временную ссылку на элемент массива
GetData Разрешает непосредственный доступ к элементам массива

Увеличение размера массива

SetAtGrow Присваивание нового значения элементу массива
Add Добавляет новый элемент в конец массива
Append Добавляет новый массив к существующему
Copy Копирует массив в существующий

Вставки и удаления

InsertAt Вставляет новый элемент в массив
RemoveAt Удаляет элемент из массива

Перегруженные операции

operator [] Позволяет получить или изменить значение элемента массива по его индексу

Конструкторы

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 );
throw( CMemoryException );

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 Создает объект список

Доступ к голове и хвосту

GetHead Возвращает головной элемент непустого списка
GetTail Возвращает хвостовой элемент непустого списка

Обработка

RemoveHead Удаляет элемент из головы списка
RemoveTail Удаляет элемент из хвоста списка
AddHead Добавляет элемент или все элементы другого списка в голову данного
AddTail Добавляет элемент или все элементы другого списка в хвост данного
RemoveAll Удаляет все элементы списка

Итерации

GetHeadPosition Возвращает позицию головного элемента списка
GetTailPosition Возвращает позицию хвостового элемента списка
GetNext Возвращает следующий элемент для итерации
GetPrev Возвращает предыдущий элемент для итерации

Получение и модификация элементов

GetAt Возвращает значение элемента в данной позиции
SetAt Изменяет значение элемента в данной позиции
RemoveAt Удаляет элемент с заданной позицией

Вставки

InsertBefore Вставляет новый элемент перед данной позицией
InsertAfter Вставляет новый элемент после данной позицией

Поиск

Find Возвращает позицию элемента по значению указателя
FindIndex Возвращает позицию элемента, заданную индексом, начинающимся с нуля

Атрибуты

GetCount Возвращает число элементов списка
IsEmpty Возвращает состояние списка (пустой или нет)

 

 

Конструктор

 

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; просмотров: 587.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...