Шаг 59 - CArray и наши классы

Создание проекта

Создаем консольное приложение Win32 c поддержкой MFC.

Организация массивов By Nicolay.

Удобно, для организации массивов, элементами которых являются собственные типы, пользоваться шаблонами MFC. Рассмотрим шаблон класса CArray: Шаблон класса СArray имеет вид:

template < class TYPE, clаss ARG_Type > class CArray : public CObject

где TYPE - ТИП элементов, хранящихся в массиве. ARG - ссылка на тип заданный первым параметром. Сохраняю в динамическом массиве объекты типа CString:

typedef  CArray  < CString, CString* > SArray 
SArray aM1, aM2;

Тоже самое можно сделать и для любого Вашего типа:

typedef  CArray  < CMyClass, CMyClass* > MyArray 
MyArray aM1, aM2;

Все функции доступа к элементам массива описанные в шаге 58 имеют место и здесь. Часто, целесообразно хранить в массиве не сами элементы, а указатели на них. Для этого можно использовать шаблоны классов CTypedPtrArray. Шаблон класса CTypedPtrArray имеет вид:

template  <  class  Base_Class,  clаss  Type*  > 

где Base_Class - базовый класс для хранения указателей. Type - указатель на тип элементов массива. Для Базового класса нужно использовать классы массивов, не использующих шаблоны! Например, те которые были представлены в шаге 58 (CObArray, CptrArray: etc).

 typedef  CTypedPtrArray  < CPtrArray, MyClass*> 
DArray; DArray aM;

Как видно, пока речь шла о одномерных массивах. Но не трудно догадаться как, например, из последнего разобранного класса сделать и 3D массивы.

Создаем код

#include "stdafx.h"
#include "afxwin.h"
#include "iostream.h"
#include "afxtempl.h" // здесь шаблоны массивов
class CMyTest // описываем наш класс
{
public:
CMyTest(); // конструктор
CMyTest(int ix,int iy, int iz); // другой конструктор
CMyTest(CMyTest& cmtest); // конструктор копий
int GetZ();
int GetX();
int GetY();
private:
int x;
int y;
int z;
};
int CMyTest::GetZ()
{
return z;
}
int CMyTest::GetX()
{
return x;
}

int CMyTest::GetY()
{
return y;
}
CMyTest::CMyTest(CMyTest& cmtest)
{
x=cmtest.GetX();
y=cmtest.GetY();
z=cmtest.GetZ();
}
CMyTest::CMyTest(int ix,int iy, int iz)
{
x=ix;
y=iy;
z=iz;
}
CMyTest::CMyTest()
{
x=0;
y=0;
z=0;
}
CArray <CMyTest,CMyTest> TestArray;
void main()
{
TestArray.SetSize(0,1); // начальный размер массива
CMyTest cm(1,1,1); // наш класс
TestArray.Add(cm); // добавляем
TestArray.Add(CMyTest(1,1,2)); // еще
TestArray.Add(CMyTest(1,1,3)); // еще
cout << TestArray.GetSize() << endl; // получить размер
TestArray.RemoveAt(2); // удалить второй
cout << "---------" << endl;
for (int x=0;x < TestArray.GetSize();x++) cout << TestArray[x].GetZ() << endl; // вывести на экран
}

Описание

В данном примере демонстрируется, как можно добавлять собственные классы в массивы на основе шаблона CArray. Хотя для полной реализации в моем классе не хватает функций. Вы должны понять принцып. Шаблон массива действует на основе некоторых стандартных методов, которые должны быть описаны в Вашем классе.

Давайте посмотрим код в отладчике. Что происходит при добавлении класса. Если мы добавляем класс то вызовется конструктор копий.

59_1.gif (3355 b)

Если мы добавляем класс то вызовется конструктор копий.

59_2.gif (1531 b)

Нормальное использование нашего класса в шаблоне массива требует перегрузки больного количество операций и не только конструкторов, но и операций сравнения и так далее.

Если не описать перегруженную операцию, но пробовать ей воспользоваться, то при компиляции получим ошибку. И не у меня в программе, а в коде MFC от Microsoft, что страшно меня возмущает. Когда я первый раз это увидел, то был немного в растерянности, так как не мог понять, кто ошибся то?

Шпаргалка

Описать класс со всеми необходимыми перегруженными операциями.

class CMyTest				// описываем наш класс
{
..........
CMyTest(); // конструктор
CMyTest(int ix,int iy, int iz); // другой конструктор
CMyTest(CMyTest& cmtest); // конструктор копий
..........
};

Подключить заголовочный файл с шаблонами.

#include "afxtempl.h"			// здесь шаблоны массивов

Создать объект массива на основе шаблона.

CArray <CMyTest,CMyTest>  TestArray;

Пользуйтесь на здоровье.

........
TestArray[x].GetZ()
........

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 29.10.99 (обновлено 16.07.2001)