Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Снова динамический массив, тема для FAQ 
:(
    Опции темы
Fantasist
Дата 30.9.2002, 03:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Что-то этот вопрос так часто задают, что я думаю пара поместить его туда.
Чтобы народ не писал такие ужастики как:

Код

float **Massiv;  
Massiv=new float*[height];  
for (int i=0;i<height;i++)  
  Massiv[i]=new float[width];  
.......  
.......  
for (int i=0;i<height;i++)  
   delete []Massiv[i];  
delete []Massiv;  


Итак, три способа создания динамических массивов:

1. Самодельный ручной.

Код

template <class _Tp>
class CDynArray
{
private:
 _Tp *buff;
 int m_x_size;
 int m_y_size;
public:
 CDynArray(): buff(0), m_x_size(0), m_y_size(0) {};
 CDynArray(const CDynArray<_Tp>& arr)
 {
     SetSize(arr.XSize(),arr.YSize());
     for(int i=0;i<m_x_size*m_y_size;++i)
       buff[i]=arr.buff[i];
 }
 ~CDynArray() {if (buff)  delete[] buff;};

 void SetSize(int x,int y)
 {
   if (buff) delete[] buff;
   if (x*y==0) buff=0;
   else
      buff=new _Tp[(m_x_size=x)*(m_y_size=y)];
 };

 _Tp& operator(int x,int y)
 {
   if (buff==0) throw "Not initialized";
   if ((x<0)||(x>=m_x_size)||(y<0)||(y>=m_y_size)) throw "Out of bounds";  
   return buff[x*m_y_size+x];
 };
 
 bool IsEmpty() {return buff==0;};
 int XSize() {return m_x_size;};
 int YSize() {return m_y_size;};
};

Кому не нравятся шаблоны, могут заменить все _Tp, на какой-нибудь float(или что там больше нравится), и выкинуть строчку с template.

2. C использованием уже готовых.

Код

template <class _Tp>
class CDynArray
{
private:
 CArray<_Tp,_Tp&> arr;
 int m_x_size;
 int m_y_size;
public:
 CDynArray(): m_x_size(0), m_y_size(0) {};
 CDynArray(const CDynArray<_Tp>& arr)
 {
    m_x_size=x; m_y_size=y;
    Copy(arr.arr);
 };
 ~CDynArray() {};

 void SetSize(int x,int y)  
 {
   arr.SetSize((m_x_size=x)*(m_y_size=y));
 };

 _Tp& operator(int x,int y)
 {
   return arr[x*m_y_size+y];
 };

 int XSize() {return m_x_size;};
 int YSize() {return m_y_size;};
};

Другую функциональность СArray можно добавить по вкусу.

P.S. Вообще-то, наверное, лучше использовать std::vector вместо СArray (хотя это тоже вопрос ситуации) но последний первым пришел мне на ум, как более известный начинающим(мне так кажется).

3. Разряженный массив.
(массив, имеющий большие, необязательно определенные, границы но в котором храниться достадочно малое количество элементов)

То есть этот массив оптимизирован на использование минимального количества памяти, по сравнению со скоростью доступа к элементам.
Можно, конечно, тоже самому написать целый класс, но удобнее(и скорее всего эффективнее) воспользоваться уже готовым ассоциативным массивом. Буду непоследователен, и вместо CMap использую std::map. Смысл от этого, впрочем, не меняется.

Код


template <class _Tp>
class CSparseArray
{
private:
 struct ArrIndex
 {
   int m_x,m_y;
   ArrIndex() {};
   ArrIndex(int x, int y): m_x(x), m_y(y) {};
   ArrIndex(const ArrIndex& ind): m_x(ind.m_x), m_y(ind.m_y) {};
   ArrIndex& operator=(const ArrIndex ind) {m_x=arr.m_x; m_y=ind.m_y; return *this;};
   bool operator<(const ArrIndex& arr) {return  m_x==ind.m_x ? m_y<ind.m_y : m_x<ind.m_x };
 };

std::map<ArrIndex,_Tp> arr;
public:
 _Tp& operator(int x,int y) {return arr[ArrIndex(x,y)];};
};

Такой массив, благодаря map, не нуждается в инициализации. Его можно использовать так:
Код

CSparseArray<int> marr;
marr(1,3)=5; //присвоим значение.
int i=marr(1,3); //i==5;
int j=marr(3,3); // marr(3,3)==0 , j==0


Думаю, фантазии у всех хватит чтобы из этого сделать трехмерный массив, дополнить нужный функционал, в общем, сделать то, что удовлетворит их потребностям.

P.S. Большая просьба к кому-нибудь проверить этот код и исправить ошибки, де таковые обнаружаться. Неплохо бы еще протестировать - все работать будет, но на практике могут всплыть какие-нибудь моменты. Спасибо.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1547 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.