forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   CArray - класс для работы с динамическими массивами (http://forum.boolean.name/showthread.php?t=4036)

haedim 30.07.2007 16:26

CArray - класс для работы с динамическими массивами
 
Вот, наконец-то нашел хороший класс для работы с динамическими массивами в C++. Мне этого всегда не хватало.
Надеюсь, и вам будет полезен.
CArray.h:
Код:

// ---------------------------------------------------------------------------
// CArray.h - C++ File
// Copyright ©2005 Michael B. Comet  All Rights Reserved
// ---------------------------------------------------------------------------
//
// DESCRIPTION:
// The header for template for dynamic arrays like Maya...
//
// USAGE:
// Usually it is a good idea to simplify using templates by using a typedef.
// For example if you wanted to make an array of ints....
//
//  typedef CArray<int> CIntArray ;
//
//  Then you can make variables like:      CIntArray theArr ;  // Create object
//            theArr.setLength(100) ;  // grow the array
//
//  and so on.  Of course Maya already has an MIntArray, but this way you can
//  create similar array objects of your own classes, or of classes that Maya didn't
// provide it for, like matrices:
//
//  typedef CArray<MMatrix> MMatrixArray ;
//
// ***note if you use this with your own classes, you will have to make sure your
// class implements the "friend ostream& operator<<" proc so that the array
// template can properly do a cout or such on the element.
//
//
// AUTHOR:
// Michael B. Comet - [email protected]
//
// VERSIONS:
// 10/15/05 - comet - Initial Rev
//
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#ifndef CCARRAY_H
#define CCARRAY_H 1
#include <iostream>
using namespace::std ;
// ---------------------------------------------------------------------------
template <class TYPE>
class CArray
{
private:
 TYPE  *ptr ;  // ptr to array of data
 unsigned uEleAlloc ; // actual size we currently are
 unsigned uEle ;  // number of elements that appears to user
 unsigned uGrowSize ; // How much to grow each time min
public:
 CArray()        // Blank constructor
  {
  ptr = NULL ;  uEleAlloc = uEle = 0 ;  uGrowSize = 64 ;
  }
 CArray(CArray &other)    // Copy constructor
  {
  ptr = NULL ;  uEleAlloc = uEle = 0 ;  uGrowSize = 64 ;
  copy(other);
  }
 
 CArray( const TYPE *src, unsigned count) // Copy by pointer constructor
  {
  ptr = NULL ;  uEleAlloc = uEle = 0 ;  uGrowSize = 64 ;
  setLength(count) ;
  unsigned u ;
  for (u=0; u < uEle; ++u)
  ptr[u] = src[u] ;
  }
 CArray( unsigned initialSize, TYPE initialValue)  // Initialization constructor
  {
  ptr = NULL ;  uEleAlloc = uEle = 0 ;  uGrowSize = 64 ;
  setLength(initialSize) ;
  unsigned u ;
  for (u=0; u < uEle; ++u)
  ptr[u] = initialValue ;
  }
 ~CArray()      // Destructor
  {
  clear() ;
  }
 
 void clear(void) ;  // free stuff
 bool setLength(unsigned length) ;  // Set to new size
 unsigned length(void)    // Return cur length
  {
  return uEle;
  }
 bool set(TYPE data, unsigned index) ;  // Set a given element.  Does bounds checking but not growing.
 bool get(TYPE &data, unsigned index) ;  // Get a given element.  Does bounds checking but not growing.
 bool get(TYPE *data) ;      // Copies all elements to the given pointer of type.
 bool remove(unsigned index) ;    // Remove a given element at the provided index
 bool insert(TYPE data, unsigned index) ; // Insert a given element at the provided index
 bool append(TYPE data) ;    // Append data to end of array, growing array by 1.
 bool copy(CArray &source)  // Copy all the elements from source to this array
  {
  clear() ;
  unsigned uLen = source.length() ;
  setLength( uLen );
  unsigned u;
  for (u=0; u < uEle; ++u)
  ptr[u] = source.ptr[u] ;
  return true ;
  }
 void setSizeIncrement( unsigned newIncrement) // Set grow size
  {
  uGrowSize = newIncrement ;
  if (uGrowSize < 1)
  uGrowSize = 1 ;
  }
 unsigned sizeIncrement(void) const  // Get grow size
  {
  return uGrowSize ;
  }
 const TYPE& operator[](unsigned index) const  // No bounds check, get element
  {
  return ptr[index];
  }
 
 TYPE& operator[](unsigned index)    // No bounds check, set element
  {
  return ptr[index];
  }
 CArray& operator=(CArray &other)  // Copy elements from other to this array
  {
  copy(other) ;
  return *this ;
  }
 friend ostream& operator<<(ostream &os, const CArray &arr)
  {
  os << "(length=" << arr.uEle << ") [" ;
  unsigned u ;
  for (u=0; u < arr.uEle; ++u)
  {
  os << arr.ptr[u] ;
  if (u < arr.uEle-1)
    os << ", " ;
  else
    os << "]" ;
  }
  return os ;
  }
} ;
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// CArray Class Implementation
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/*
 * void CArray<TYPE>::clear() - free mem
 */
template <class TYPE>
void CArray<TYPE>::clear(void)
{
 if (ptr != NULL)
  delete [] ptr ;
 ptr = NULL ;
 uEleAlloc = 0 ;
 uEle = 0 ;
}
 
// ---------------------------------------------------------------------------
/*
 * CArray<type>::setLength() - Set size of array.  Returns true on success
 */
template <class TYPE>
bool CArray<TYPE>::setLength(unsigned length)
{
 if (length == 0)
  {
  clear() ;
  return true ;
  }
 // Alloc new storage
 TYPE *newptr=NULL ;
 unsigned uNewEleAlloc = (( length / uGrowSize) + 1) * uGrowSize ;
 // Now see if we need to alloc new, and do so only if needed!
 // Needed means either the amt we need is greater than what we have already
 // ...or if the amt is half or less than half, to free RAM we'll realloc smaller
 //
 if (uNewEleAlloc > uEleAlloc || uNewEleAlloc <= (uEleAlloc / 2) )
  {
  newptr = new TYPE [uNewEleAlloc] ;
  if (newptr == NULL)  // memory alloc error!
  return false ;
  // Now copy old elements over to new array.
  // Up the the old amt or user set new length, whichever is smaller.
  unsigned u;
  for (u=0; u < uEle && u < length; ++u)
  {
  newptr[u] = ptr[u] ;
  }
  // Update all the current info...
  if (ptr != NULL)
  delete [] ptr ;
  ptr = newptr ;
  uEleAlloc = uNewEleAlloc ;
  }
 uEle = length ;
 return true ;
}
 
// ---------------------------------------------------------------------------
/*
 * CArray<TYPE>::set() - Set a given element.  Does bounds checking but not growing.
 */
template <class TYPE>
bool CArray<TYPE>::set(TYPE data, unsigned index)
{
 if (index >= uEle || ptr == NULL)
  return false ;
 ptr[index] = data ;
 return true ;
}
// ---------------------------------------------------------------------------
/*
 * CArray<TYPE>::get() - Get a given element.  Does bounds checking but not growing.
 */
template <class TYPE>
bool CArray<TYPE>::get(TYPE &data, unsigned index)
{
 if (index >= uEle || ptr == NULL)
  return false ;
 data = ptr[index] ;
 return true ;
}
// ---------------------------------------------------------------------------
/*
 * CArray<TYPE>::get() - Copies all elements to the given pointer of type.  Ptr should be big enough to hold arr.
 */
template <class TYPE>
bool CArray<TYPE>::get(TYPE *data)
{
 if (data == NULL)
  return false ;
 unsigned u ;
 for (u=0; u < uEle; ++u)
  data[u] = ptr[u] ;
 return true ;
}
 
// ---------------------------------------------------------------------------
/*
 * CArray<TYPE>::remove() - Remove a given element at the provided index
 */
template <class TYPE>
bool CArray<TYPE>::remove(unsigned index)
{
 if (uEle == 0 || ptr == NULL)
  return false ;
 // Now starting with the element we are removing, work up
 // coping each next value down to the current spot...
 //
 unsigned u ;
 for (u=index; u < uEle-1 ; ++u)
  {
  ptr[u] = ptr[u+1] ;
  }
 // Now just setLength to 1 less than we had.  This will either
 // simply change the uEle value, or if we shrunk enough, realloc and
 // free some ram.
 setLength( uEle-1 ) ;
 return true ;
}
// ---------------------------------------------------------------------------
/*
 * CArray<TYPE>::insert() - insert a given element at the provided index
 */
template <class TYPE>
bool CArray<TYPE>::insert(TYPE data, unsigned index)
{
 // First setLength up one so we have room
 setLength( uEle+1 ) ;
 // Now starting with the last element work back
 // until we get to the one we are inserting at and copy forward.
 //
 unsigned u ;
 for (u=uEle-1; u > index; --u)
  {
  ptr[u] = ptr[u-1] ;
  }
 // Finally insert new value
 ptr[index] = data ;
 return true ;
}
// ---------------------------------------------------------------------------
 
/*
 * CArray<TYPE>::append() - Append data to end of array, growing array by 1.
 */
template <class TYPE>
bool CArray<TYPE>::append(TYPE data)
{
 // First setLength up one so we have room
 setLength( uEle+1 ) ;
 // Finally insert new value
 ptr[uEle-1] = data ;
 return true ;
}
// ---------------------------------------------------------------------------
#endif // CCARRAY_H

Сайт автора - http://www.comet-cartoons.com.

impersonalis 30.07.2007 16:59

Re: CArray - класс для работы с динамическими массивами
 
Вообще-то он встроенный (насколько я помню).
См также
CStringArray
CPtrArray
CUintArray

haedim 30.07.2007 17:13

Re: CArray - класс для работы с динамическими массивами
 
Цитата:

Сообщение от impersonalis
Вообще-то он встроенный

Есть в MFC класс с таким же названием. Но оно - единственное, что есть общего у него с представленным выше ;) .

impersonalis 22.04.2011 12:39

Ответ: CArray - класс для работы с динамическими массивами
 
прямой линк
http://comet-cartoons.com/MELfiles/CArray.h

ISergey 22.04.2011 16:44

Ответ: CArray - класс для работы с динамическими массивами
 
А std::vector уже не годится?

impersonalis 22.04.2011 17:07

Ответ: CArray - класс для работы с динамическими массивами
 
Некропостер!!!
Вообще - очень даже может быть. Я обычно пишу с MFC (там есть контейнеры необходимые) или (если требуется специфическая функциональность) реализую списки сам.
Так что, возможно - предложенный Вами вариант оптимален. Мне сказать нечего - скажите Вы.

HolyDel 22.04.2011 18:00

Ответ: CArray - класс для работы с динамическими массивами
 
Цитата:

Некропостер!!!
ето ты самому себе сказал чтоли?)))

Цитата:

А std::vector уже не годится?
он будет явно лучше приведенного класса в нормальных приложениях. хотя-бы за счет того - что вектор увеличивает своб емкость не на +1 на вставку а на какой то коэффициент от текущего размера.

ISergey 22.04.2011 18:03

Ответ: CArray - класс для работы с динамическими массивами
 
Цитата:

Сообщение от impersonalis (Сообщение 186549)
Некропостер!!!

К чему это? У меня показано что вы тему подняли.. ( Сегодня 10:39 ) (Может глюк какой то =) )
Цитата:

Я обычно пишу с MFC (там есть контейнеры необходимые) или (если требуется специфическая функциональность) реализую списки сам.
В MFC я не заглядывал. Мне с головой хватает стандартной библиотеки..

impersonalis 22.04.2011 19:17

Ответ: CArray - класс для работы с динамическими массивами
 
Цитата:

Сообщение от HolyDel (Сообщение 186554)

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

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

Цитата:

К чему это? У меня показано что вы тему подняли.. ( Сегодня 10:39 ) (Может глюк какой то =) )
юмор типа

HolyDel 22.04.2011 22:12

Ответ: CArray - класс для работы с динамическими массивами
 
Цитата:

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

impersonalis 22.04.2011 22:15

Ответ: CArray - класс для работы с динамическими массивами
 
Цитата:

Сообщение от HolyDel (Сообщение 186572)
у мну есть жесткое убеждение, что, дореализация типового функциона есть зло.

согласен, я употребил это в значении "такую очевидность, автор сабжа реализовал":
Код:

void setSizeIncrement( unsigned newIncrement) // Set grow size
правда, несколько своеобразно (добавление 1-ого элемента расширяет набор только на 1, изменения работают в setLength ).

В следующий раз посмотрю std::vector - уговорили.

ffinder 22.04.2011 23:10

Ответ: CArray - класс для работы с динамическими массивами
 
Цитата:

Сообщение от impersonalis (Сообщение 186573)
В следующий раз посмотрю std::vector - уговорили.

посмотри в его исходники (троллфейс.jpg)

impersonalis 23.04.2011 00:54

Ответ: CArray - класс для работы с динамическими массивами
 
да сабж - тоже не фонтан по реализации оказался при рассмотрении ближайшем =(


Часовой пояс GMT +4, время: 21:32.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot