Prosta dynamiczna tablica (na wskaźniki obiektów)
Czy ktoś mi podpowie, gdzie jest błąd?
//---------------------------------------------------------------------------
#ifndef pointer_arrayH
#define pointer_arrayH
//---------------------------------------------------------------------------
//#define TEST
//#include <stdexcept>
//#include <iostream>
//---------------------------------------------------------------------------
namespace mylib {
//----------------------------------------------------------------------
template <typename T, unsigned N = 10>
class pointer_array_type
{
// SKLADNIKI PRYWATNE ----------------------------
typedef T* pointer_type;
// static constans
static const unsigned static_size = N;
// pointer
pointer_type temp;
typedef struct
{
bool aktywna;
unsigned rozmiar;
unsigned kolejny_index;
pointer_type* ptr;
} array_type;
array_type tablica_A;
array_type tablica_B;
array_type* adres;
// SKLADOWE FUNKCJE PRYWATNE ---------------------
bool aktualizuj_tablice(int przyrost);
bool range_check (unsigned index)
{return index < adres->kolejny_index ? true : false; }
public:
// KONSTRUKTOR I DESTRUKTOR ----------------------
pointer_array_type(void);
~pointer_array_type(void);
// FUNKCJE DOSTEPU -------------------------------
unsigned Add(pointer_type pointer);
pointer_type Item(int index);
bool Erase(int index);
int Size(void);
void Clear(void);
// front() and back()
pointer_type Front() {return adres->ptr[0];}
pointer_type Back() {return adres->ptr[adres->kolejny_index - 1];}
// przypisz jedna wartosc wszystkim elementom
void assign(pointer_type pointer)
{
for(unsigned i = 0; i < adres->rozmiar; i++)
adres->ptr[i] = pointer;
}
};
// AKTUALIZUJ_TABLICE --------------------------------------------------
template <typename T, unsigned N>
bool pointer_array_type<T, N>::aktualizuj_tablice(int przyrost)
{
// jesli tablica 'A' jest aktywna
if(tablica_A.aktywna)
{
#ifdef TEST
//std::cout << " f: atualizuj_tablice() - aktywacja tablicy B \n";
#endif
//------------------------------------------------------------
// nowy rozmiar tablicy
int count = przyrost + tablica_A.rozmiar;
// tworzymy dynamicznie nowa tablice krotek, o nowym
// rozmiarze, jesli zabraknie pamieci, adres przyjmie
// wartosc 0
tablica_B.ptr = new pointer_type[count];
// jesli zabraklo pamieci wypisz komunikat, powroc do
// poprzedniego rozmiaru tablicy aktywnej i zwroc 'false'
if(tablica_B.ptr == 0)
{
tablica_B.rozmiar -= przyrost;
return false;
}
// nowy rozmiar tablicy
tablica_B.rozmiar = count;
// ustaw tablica 'B' jako aktywna
tablica_B.aktywna = true;
// kopiuj liczbe krotek
tablica_B.kolejny_index = tablica_A.kolejny_index;
// przekopiuj pola krotek do odpowiednich krotek nowej tablicy
// a poprzednia komorke wyzeruj (wyzeruj adres), wykorzystywany
// domyslny operator przypisania
count = tablica_A.kolejny_index;
for(int i = 0; i < count; i++)
tablica_B.ptr[i] = tablica_A.ptr[i];
// zwolnij pamiec
delete [] tablica_A.ptr;
// ustaw tablice 'A' jako nieaktywna
tablica_A.aktywna = false;
// wyzeruj wartosci
tablica_A.kolejny_index = 0;
tablica_A.rozmiar = 0;
tablica_A.ptr = 0;
// ustaw adres pomocniczy na aktywna tablice
adres = &tablica_B;
return true;
}
// analogicznie, jesli tablica 'B' jest aktywna
if(tablica_B.aktywna)
{
#ifdef TEST
//std::cout << " f: atualizuj_tablice() - aktywacja tablicy A \n";
#endif
//------------------------------------------------------------
int count = przyrost + tablica_B.rozmiar;
tablica_A.ptr = new pointer_type[count];
if(tablica_A.ptr == 0)
{
tablica_A.rozmiar -= przyrost;
return false;
}
tablica_A.rozmiar = count;
tablica_A.aktywna = true;
tablica_A.kolejny_index = tablica_B.kolejny_index;
count = tablica_B.kolejny_index;
for(int i = 0; i < count; i++)
tablica_A.ptr[i] = tablica_B.ptr[i];
delete [] tablica_B.ptr;
tablica_B.aktywna = false;
tablica_B.kolejny_index = 0;
tablica_B.rozmiar = 0;
tablica_B.ptr = 0;
adres = &tablica_A;
}
return true;
}
// KONSTRUKTOR ---------------------------------------------------------
template <typename T, unsigned N>
pointer_array_type<T, N>::pointer_array_type(void)
{
#ifdef TEST
// std::cout << " f: konstruktor() \n";
#endif
//-----------------------------------------------------------------
// ustanawiamy tablice 'A' za aktywna
tablica_A.aktywna = true;
tablica_A.kolejny_index = 0;
tablica_A.rozmiar = static_size;
tablica_A.ptr = new pointer_type[static_size];
// ustaw adres pomocniczy na powyzsza (aktywna) tablice
adres = &tablica_A;
assign(0);
// tablice 'B' za nieaktywna
tablica_B.aktywna = false;
tablica_B.kolejny_index = 0;
tablica_B.rozmiar = 0;
tablica_B.ptr = 0;
}
// DESTRUKTOR ----------------------------------------------------------
template <typename T, unsigned N>
pointer_array_type<T, N>::~pointer_array_type(void)
{
#ifdef TEST
// std::cout << " f: destruktor() \n";
#endif
//-----------------------------------------------------------------
for(unsigned i = 0; i < adres->kolejny_index; i++)
if(adres->ptr[i])
delete adres->ptr[i];
delete [] adres->ptr;
}
// ADD -----------------------------------------------------------------
template <typename T, unsigned N>
inline unsigned pointer_array_type<T, N>::Add(T* pointer)
{
// sprawdz, czy jest jeszcze 'wolna komorka'
if(adres->kolejny_index == adres->rozmiar)
// jesli nie ma, powieksz tablice o wartosc
if(!aktualizuj_tablice(static_size))
// jesli nie udalo sie powiekszyc, wroc
return -1;
adres->ptr[adres->kolejny_index] = pointer;
// powieksz index o 1
adres->kolejny_index++;
#ifdef TEST
//std::cout << " f: add() size = " << adres->ptr[size() - 1] << "\n";
#endif
//-----------------------------------------------------------------
return (adres->kolejny_index - 1);
}
// ITEM ----------------------------------------------------------------
template <typename T, unsigned N>
inline T* pointer_array_type<T, N>::Item(int index)
{
#ifdef TEST
//std::cout << " f: Item() ";
#endif
//-----------------------------------------------------------------
if(!range_check(index))
return temp;
return adres->ptr[index];
}
// ERASE ---------------------------------------------------------------
template <typename T, unsigned N>
inline bool pointer_array_type<T, N>::Erase(int index)
{
if(!range_check(index))
return false;
delete adres->ptr[index];
for(int i = index; i < adres->kolejny_index; i++)
adres->ptr[i] = adres->ptr[i + 1];
adres->kolejny_index--;
#ifdef TEST
// std::cout << " f: erase() " << size() << "\n";
#endif
//-----------------------------------------------------------------
if((adres->rozmiar - adres->kolejny_index) >= static_size)
aktualizuj_tablice((-1) * static_size);
return true;
}
// SIZE ----------------------------------------------------------------
template <typename T, unsigned N>
int pointer_array_type<T, N>::Size(void)
{
return adres->kolejny_index;
}
// CLEAR ---------------------------------------------------------------
template <typename T, unsigned N>
inline void pointer_array_type<T, N>::Clear(void)
{
int count = adres->kolejny_index;
for(int i = count - 1; i >= 0; i--)
Erase(i);
}
//---------------------------------------------------------------------------
}; // end of namespace mylib
//---------------------------------------------------------------------------
#endif