|
30.07.2007, 16:26
|
#1
|
Разработчик
Регистрация: 16.09.2006
Сообщений: 354
Написано 10 полезных сообщений (для 2 пользователей)
|
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.
|
(Offline)
|
|
30.07.2007, 16:59
|
#2
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Re: CArray - класс для работы с динамическими массивами
Вообще-то он встроенный (насколько я помню).
См также
CStringArray
CPtrArray
CUintArray
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
30.07.2007, 17:13
|
#3
|
Разработчик
Регистрация: 16.09.2006
Сообщений: 354
Написано 10 полезных сообщений (для 2 пользователей)
|
Re: CArray - класс для работы с динамическими массивами
Сообщение от impersonalis
Вообще-то он встроенный
|
Есть в MFC класс с таким же названием. Но оно - единственное, что есть общего у него с представленным выше .
|
(Offline)
|
|
22.04.2011, 12:39
|
#4
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
22.04.2011, 16:44
|
#5
|
AnyKey`щик
Регистрация: 10.11.2008
Сообщений: 18
Написано 4 полезных сообщений (для 5 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
А std::vector уже не годится?
__________________
Шутить надо так, чтобы потом не было мучительно больно за бесцельно выбитые зубы.
|
(Offline)
|
|
22.04.2011, 17:07
|
#6
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
Некропостер!!!
Вообще - очень даже может быть. Я обычно пишу с MFC (там есть контейнеры необходимые) или (если требуется специфическая функциональность) реализую списки сам.
Так что, возможно - предложенный Вами вариант оптимален. Мне сказать нечего - скажите Вы.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
22.04.2011, 18:00
|
#7
|
☭
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений (для 2,707 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
ето ты самому себе сказал чтоли?)))
А std::vector уже не годится?
|
он будет явно лучше приведенного класса в нормальных приложениях. хотя-бы за счет того - что вектор увеличивает своб емкость не на +1 на вставку а на какой то коэффициент от текущего размера.
|
(Offline)
|
|
22.04.2011, 18:03
|
#8
|
AnyKey`щик
Регистрация: 10.11.2008
Сообщений: 18
Написано 4 полезных сообщений (для 5 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
Сообщение от impersonalis
Некропостер!!!
|
К чему это? У меня показано что вы тему подняли.. ( Сегодня 10:39 ) (Может глюк какой то =) )
Я обычно пишу с MFC (там есть контейнеры необходимые) или (если требуется специфическая функциональность) реализую списки сам.
|
В MFC я не заглядывал. Мне с головой хватает стандартной библиотеки..
__________________
Шутить надо так, чтобы потом не было мучительно больно за бесцельно выбитые зубы.
|
(Offline)
|
|
22.04.2011, 19:17
|
#9
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
Сообщение от HolyDel
он будет явно лучше приведенного класса в нормальных приложениях. хотя-бы за счет того - что вектор увеличивает своб емкость не на +1 на вставку а на какой то коэффициент от текущего размера.
|
сомнительное (но при этом легкореализуемое) преимущество.
Далеко не везде такая экстраполяция выделений актуальна и даже наоборот. Ну и вдобавок актуальнее выглядит реализованная везде функция предвыделения памяти.
К чему это? У меня показано что вы тему подняли.. ( Сегодня 10:39 ) (Может глюк какой то =) )
|
юмор типа
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
22.04.2011, 22:12
|
#10
|
☭
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений (для 2,707 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
но при этом легкореализуемое
|
у мну есть жесткое убеждение, что, дореализация типового функциона есть зло.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
22.04.2011, 22:15
|
#11
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
Сообщение от HolyDel
у мну есть жесткое убеждение, что, дореализация типового функциона есть зло.
|
согласен, я употребил это в значении "такую очевидность, автор сабжа реализовал":
void setSizeIncrement( unsigned newIncrement) // Set grow size
правда, несколько своеобразно (добавление 1-ого элемента расширяет набор только на 1, изменения работают в setLength ).
В следующий раз посмотрю std::vector - уговорили.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
22.04.2011, 23:10
|
#12
|
Дэвелопер
Регистрация: 10.09.2007
Сообщений: 1,442
Написано 793 полезных сообщений (для 1,460 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
Сообщение от impersonalis
В следующий раз посмотрю std::vector - уговорили.
|
посмотри в его исходники (троллфейс.jpg)
|
(Offline)
|
|
23.04.2011, 00:54
|
#13
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: CArray - класс для работы с динамическими массивами
да сабж - тоже не фонтан по реализации оказался при рассмотрении ближайшем =(
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 06:21.
|