Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.09.2009, 19:52   #1
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию TImage в сочетании с new и std::pair

Доброго времени суток!
Пишу сейчас игру (условно говоря - РПГ), решил сделать в ней буфер картинок для централизованного хранения и рисования объектов карты. Картинки храню в ассоциативном массиве, проиндексированном по AnsiString (ID картинки). Сами картинки хранятся в виде битмапов в папке с экзешником. При загрузке картинок возникают проблемы с TImage.
Код:
ImageBuffer::ImageBuffer()
   {
   TStringList* ImageFiles = new TStringList;
   ImageFiles -> LoadFromFile("images.txt");   //Информация о расположении картинок в виде ID=Image_path
   AnsiString s;
   int id, pos;
   AnsiString filename;
   TImage* LoadingImage = new TImage;
   for (int i = 0; i < ImageFiles -> Count; i++)
      {
      s = ImageFiles -> Strings[i];
      pos = s.Pos("=");
      id = s.SubString(0, pos - 1).ToInt();   //Выделяем ID
      filename = s.SubString(pos + 1, s.Length() - pos);   //Выделяем путь
      LoadingImage -> Picture -> LoadFromFile(filename);
      std::pair<int, TImage> IndexedImage(id, LoadingImage);
      ImageList.insert(IndexedImage);   //Добавляем в map новую картинку
      }
   delete LoadingImage;
   delete ImageFiles;
   }
Собственно проблемы две. Первая - в строке
Код:
TImage* LoadingImage = new TImage;
TImage не имеет конструктора по умолчанию, необходимо в качестве аргумента передавать указатель на TComponent. Сакральный смысл этого TComponent я не очень понимаю - для чего его надо указывать? Эксперименты показали, что если вместо такой строки написать
Код:
TImage* LoadingImage = new TImage(Form1);
то ошибка пропадает. Однако, хотелось бы узнать, что стоит за этим?)
Другая проблема - в строке
Код:
std::pair<int, TImage> IndexedImage(id, LoadingImage);
Выдает ошибку VCL style classes must be constructed using operator new.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 01.10.2009, 05:10   #2
Руслантус
Наркоман самоучка
Форумчанин
 
Аватар для Руслантус
 
Регистрация: 22.07.2007
Сообщений: 276
По умолчанию

Привет Гром!

В данном случаи:
Код:
std::pair<int, TImage> IndexedImage(id, LoadingImage);
Нужно использовать указатель на объект, а ты просто используеш объект.
Тоесть нужно так:
Код:
std::pair<int, TImage*> IndexedImage(id, LoadingImage);
По поводу твоего 1 вопроса, то там устанавливаецо некий владелец данного компонента, чтобы потом из владельца влиять на данный компонент. Не путай с родителем, его нужно будет самому устанавливать в LoadingImage->Parent.
#include <мозг.h>
Руслантус вне форума Ответить с цитированием
Старый 01.10.2009, 10:43   #3
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Руслантус, спасибо большое!)
Вроде бы разобрался!)
Только еще вопрос - нужно ли устанавливать Parent для картинки, которая сама по себе не будет видна, и единственное назначение которой - копироваться через CopyRect в PaintBox? (других действий с ней производить пока не планирую)

Все-таки никак не могу подружить pair и TImage. Билдер выкидывает ошибку
VCL style classes must be constructed using operator new
причем посылает меня в _pair.h, а конкретно в строку
Код:
pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {}
Не знаю уж, как организовать пару с имэйджем...
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же

Последний раз редактировалось Stilet; 05.10.2009 в 09:36.
Гром вне форума Ответить с цитированием
Старый 05.10.2009, 04:01   #4
Руслантус
Наркоман самоучка
Форумчанин
 
Аватар для Руслантус
 
Регистрация: 22.07.2007
Сообщений: 276
По умолчанию

Гром
Тогда ставить Parent думаю ненужно.
Если тебе просто нужно хранить изображение, то используй спец. классы.
Лучший вариант это:
Код:
Graphics::TBitmap *NewImage = new Graphics::TBitmap()
У него также есть много полезных методов.

Насчёт ошибки с pair, то покажи код.
#include <мозг.h>
Руслантус вне форума Ответить с цитированием
Старый 10.10.2009, 11:24   #5
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

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

В варианте с указателями я просто переписал код, добавив где надо звездочек:
Код:
ImageBuffer::ImageBuffer()
   {
   TStringList* ImageFiles = new TStringList;
   ImageFiles -> LoadFromFile("images.txt");
   AnsiString s;
   int pos;
   AnsiString id, filename;
   TImage* LoadingImage = new TImage(Form1);
   for (int i = 0; i < ImageFiles -> Count; i++)
      {
      s = ImageFiles -> Strings[i];
      pos = s.Pos("=");
      id = s.SubString(0, pos - 1);
      filename = s.SubString(pos + 1, s.Length() - pos);
      LoadingImage -> Picture -> LoadFromFile(filename);
      std::pair<AnsiString, TImage*>* IndexedImage = new std::pair<AnsiString, TImage*>(id, LoadingImage);
      ImageList.insert(*IndexedImage);
      }
   delete LoadingImage;
   delete ImageFiles;
   }
Соответственно, создаю пару с адресом нужного имэйджа, добавляю пару в map, удаляю имэйдж... Соответственно, получаем полную потенциально опасную ерунду... Может быть, просто не надо удалять указатель на Image?.. Что-то я и в указателях запутался...
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 10.10.2009, 11:27   #6
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Кажется, и впрямь... Перенес
Код:
  TImage* LoadingImage = new TImage(Form1);
в цикл for, закомментировал
Код:
delete LoadingImage;
и как будто бы заработало!!)))
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 10.10.2009, 14:10   #7
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Всё верно, delete ведь не указатель удаляет, а освобождает память, на которую он указывает, то есть Вы грузили картинку в память, а затем сразу же удаляли )
Код:
 std::pair<AnsiString, TImage*>* IndexedImage = new std::pair<AnsiString, TImage*>(id, LoadingImage);
Не забываем освобождать память после того, как положили пару в мэп, или, создавайте её в стеке, а не в куче. Элементы pair копируются в мэп, потому, после копирования, pair можно спокойно удалять.
netrino вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
std::vector ciaonataha Общие вопросы C/C++ 1 10.05.2009 15:50
проблема с std::ifstream.eof() alex8 Общие вопросы C/C++ 5 05.05.2009 18:24
std Викдон Общие вопросы C/C++ 3 17.02.2009 11:33
namespace std; lacost Общие вопросы C/C++ 8 22.10.2007 13:17
использование using namespace std; che Общие вопросы C/C++ 7 11.10.2007 17:13