Пятница, 19 Апреля 2024, 08:31

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » C/C++ » Простой двусвязный список
Простой двусвязный список
RenusДата: Среда, 20 Октября 2010, 11:37 | Сообщение # 1
почетный гость
Сейчас нет на сайте
Вообщем, в плане построения своей игры возникла необходимость использовать list, вместо vector, для хранения указателей на все игровые объекты. Не хватало всего одной функции - push_front, для того что бы созданные игровые объекты не обрабатывались в текущем цикле(это не правильно логически, один кадр конечно не смертельно, но шедевры собираются из мелочей...), и успевали отрисоваться в своих начальных координатах.
Попробовал просто сменить vector на list и по вылазила куча ошибок) И тут я задумался, а почему бы не попробовать написать подобный контейнер самому, только уже без десятков не нужных мне функций. Для половины критиков скажу сразу, Я не собираюсь спорить с STL и изобретать велосипед. У меня есть время и я хочу разобраться, как этот велосипед работает))
Как говорил мой школьный учитель физики:"С готовой формулой любой дурак сможет, а без слабо?" Короче хватит лирики, а то еще книгу напишу, "Как я писал на С++" tongue

Как устроены STL контейнеры я не читал, но думаю как и все шаблоны, включил логику и начал писать свой, иногда правда гуглил по форумам на счет динамических списков... Вот, то что я накидал за сегодня:

Code

//------------------------------------------------------------------------------
// Класс элемента
//------------------------------------------------------------------------------
template<class T> struct Element
{
  T   data;     // Хранимые данные элемента
  Element*    next, * prev;   // Указатели на соседние элементы
      
  Element<T>(T);      // Конструктор элемента
};

//------------------------------------------------------------------------------
// Класс листа
//------------------------------------------------------------------------------
template<class Type> class CList
{
public:
  int     size;   // Колличество элементов в листе
  Element<Type>*  first, * last;    // Указатели на крайние элементы

  void push_front(Type);    // Добавление в начало
  void push_back(Type);    // Добавление в конец
  void del_elem(int);     // Удаление элемента по номеру
  Type* get_data(int);    // Получение данных

  CList<Type>();      // Конструктор списка по умолчанию
};

// Конструктор элемента
template<class T> Element<T>::Element(T pdata) {data=pdata;}

// Конструктор листа по умолчанию
template<class Type> CList<Type>::CList()
{
  size=0;
  first=NULL;
  last=NULL;
}

// Добавление элемента в начало списка
template<class Type> void CList<Type>::push_front(Type pdata)  
{
  if (size==0)
  {
   first=new Element<Type>(pdata);
   first->next=NULL;
   first->prev=NULL;
   last=first;
   size+=1;
  }
  else
  {
   Element<Type>* temp=new Element<Type>(pdata);
   temp->next=first;
   temp->prev=NULL;
   first->prev=temp;
   first=temp;
   size+=1;  
  }
}

// Добавление элемента в конец списка
template<class Type> void CList<Type>::push_back(Type pdata)
{
  if (size==0)
  {
   last=new Element<Type>(pdata);
   last->next=NULL;
   last->prev=NULL;
   first=last;
   size+=1;
  }
  else
  {
   Element<Type>* temp=new Element<Type>(pdata);
   temp->prev=last;
   temp->next=NULL;
   last->next=temp;
   last=temp;
   size+=1;  
  }
}

// Удаление элемента из списка по номеру
template<class Type> void CList<Type>::del_elem(int num)
{
  if (num==0)
  {
   Element<Type>* temp=first;
   first->next->prev=NULL;
   first=first->next;
   delete temp;
   size-=1;
  }
  if (num==size-1)
  {
   Element<Type>* temp=last;
   last->prev->next=NULL;
   last=last->prev;
   delete temp;
   size-=1;
  }
  if (num>0 && num<size-1)
  {
   Element<Type>* temp=first;
   for (int i=0; i<num; i++)
   {
    temp=temp->next;
   }
   temp->prev->next=temp->next;
   temp->next->prev=temp->prev;
   delete temp;
   size-=1;
  }
}

// Получение данных из элемента
template<class Type> Type* CList<Type>::get_data(int num)
{
  if (num==0) {return &first->data;}
  if (num==size-1) {return &last->data;}
  if (num>0 && num<size-1)
  {
   Element<Type>* temp=first->next;
   for (int i=1; i<num; i++)
   {
    temp=temp->next;
   }
   return &temp->data;
  }
  else {return NULL;}
}

P.S. Поскольку пишу я быдлокодом, то попрошу вас товарищи, указывать на все мои ошибки, даже которые не касаются работоспособности кода.
Скажите что не правильно и что можно сделать лучше, пока я не начал писать дальше...
Всем заранее спасибо!

Добавлено (20.10.2010, 11:37)
---------------------------------------------
Хм... так отдельно в своем проекте работает, а как добавляю в игру и разбиваю на 2 файлы сср и h. При попытке создать экземпляр выдает такую гадость:

Code
1>lists.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall CList<class CObject *>::CList<class CObject *>(void)" (??0?$CList@PAVCObject@@@@QAE@XZ) в функции "void __cdecl `dynamic initializer for 'MyList''(void)" (??__EMyList@@YAXXZ)

Помогите разобраться...(((

Programmer_BIOMSOFTДата: Среда, 20 Октября 2010, 12:18 | Сообщение # 2
был не раз
Сейчас нет на сайте
где ты учился С++? Зачем такой большой код?! И о ошыбке в спрвку заглянь.... Обьясни мне почему ты не используешь векторы? dry
RenusДата: Среда, 20 Октября 2010, 18:02 | Сообщение # 3
почетный гость
Сейчас нет на сайте
Quote (Programmer_BIOMSOFT)
где ты учился С++? Зачем такой большой код?! И о ошыбке в спрвку заглянь.... Обьясни мне почему ты не используешь векторы?

Сам учу по книжкам...
Все обьекты занесены в список, у каждого есть функция Process которая вызывается на каждом кадре(собсно логика обьекта). К примеру, обрабатывается сущность игрока(самолетик), в это всремя зажат пробел, происходит выстрел(создаться пуля), так вот эта пуля должна добавляться перед обьектом ее создающим, дабы она не обрабатывалась в этом цикле(иначе ее первая отрисовка будет уже сдвинута на величину ее скорости), тоесть при привязки всех величин игры в dt(времени отрисовки) ее видимая точка появления будет смещать по оси Y в зависимости от FPS...
Решается это просто, нужно засунуть пулю в начало списка, но у вектора нету такой функции. А почему я не использую list написано в моем первом посте!
Вообщем прошу писать по теме...
P. S. Помогите с ошибкой пожалуйста...
nilremДата: Среда, 20 Октября 2010, 18:44 | Сообщение # 4
Просветленный разум
Сейчас нет на сайте
Quote (Renus)
Решается это просто, нужно засунуть пулю в начало списка, но у вектора нету такой функции.

vector.insert(vector.begin,vector element);


Windmill 2

WindMill 2D Game Engine
RenusДата: Среда, 20 Октября 2010, 19:21 | Сообщение # 5
почетный гость
Сейчас нет на сайте
Quote (nilrem)
vector.insert(vector.begin,vector element);

Да, спасибо, помогло!
Code
Obj_List.insert(Obj_List.begin(), new CBullet(x, y-120, 0, bullet1, "bullet"));

Но ведь инсерт медленно работает в векторе?
Все таки, в качестве спортивного интереса и опыта, не могли бы помочь с моим шаблонизированным списком...?

Форум игроделов » Программирование » C/C++ » Простой двусвязный список
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг