Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > хранение классов в map


Автор: LexusCheby 28.1.2007, 23:54
есть класс 
class CResourceList
{    
   map<ULONG, CImage> List;
public:
 ....
};

//по _ID заружает изображение и сохраняет в контейнере
ULONG CResourceList::LoadImage(ULONG _ID)
{
   CImage mImg;
   char* FName;
   if(!GetImgPath(_ID, &FName)) 
      return 0;
   mImg.Destroy();
   mImg.Load(FName);
   List.insert(pair<ULONG, CImage>(_ID, mImg));
   return 1;
}

Есть член, который по ID возвращает указатель на CImage(2й параметр)
ULONG CResourceList::GetCImagePtr(ULONG _ID, CImage **_ImgPtr)
{
   *_ImgPtr=&(List.find(_ID)->second);
   return 1;
}

потом при попытке вывести изображение по указателю возникает ошибка
int FWidth=pCImage->GetWidth();
 int FHeight=pCImage->GetHeight();
pCImage->StretchBlt(dc,10,10,FWidth,FHeight,FWidth*0,FHeight*0,FWidth,FHeight, SRCCOPY);

 smile 
Подскажите почему ошибка. Найти другой путь могу. Хотелось бы причину понять

Автор: Daevaorn 29.1.2007, 00:07
Цитата(LexusCheby @  29.1.2007,  00:54 Найти цитируемый пост)
возникает ошибка

какая?
Цитата(LexusCheby @  29.1.2007,  00:54 Найти цитируемый пост)
ULONG CResourceList::GetCImagePtr(ULONG _ID, CImage **_ImgPtr)
{
   *_ImgPtr=&(List.find(_ID)->second);
   return 1;
}

Лучше так:
Код

ULONG CResourceList::GetCImagePtr(ULONG _ID, CImage **_ImgPtr)
{
    map<ULONG, CImage>::iterator i = List.find(_ID);
    if( i != List.end() )
    {
        *_ImgPtr=&(i->second);
        return 1;
    }
    else
        return ERROR_CODE;
}

Автор: LexusCheby 29.1.2007, 08:50
Программа компилируется нормально, возникает ошибка времени выполнения при выводе CImage
Программа корректно проверяет различные условия, связанные с пустыми указателями.
Ошибка в ATL-овском методе ReleaseDC.
У меня подозрание, что нельзя хранить в контейнерах класс CImage. Может указатели надо хранить?.
Все то же самое вне контейнеров прекрасно работало.

Автор: _hunter 29.1.2007, 11:55
посмотри исходники -- что просиходит при копировании CImage. явно хендл просто копируется...
даже если бы при копировании создавался новый объект -- по этой же причине не рекомендуется хранить CImage -- только лишнее время уйдет на создание нового объекта.

Автор: LexusCheby 29.1.2007, 12:09
Да, hunter, тоже к таким выводам прихожу. То есть при добавлении в map копирование у нас вызывается. А оно не весь объект копирует. Как лучше тогда сделать? Что вместо CImage в map хранить. Bitmap?

Автор: _hunter 29.1.2007, 12:22
с Bitmap' ом (если имеется в виду CBitmap) будет то же самое.
храни указатели (CImage*). в принципе всегда (за исключением неких конкретных случаев) в контейнере лучше хранить указатель на объект чем сам объект...

Автор: LexusCheby 29.1.2007, 12:30
Надеюсь что хранение указателей поможет. Попробую. Напишу о результах. Если все заработает (уверен что заработает), то обязательно возьму на заметку что лучше хранить в контейнерах указатель, а не сам объект.

Автор: HappyLife 30.1.2007, 11:01
Или же почему сразу не делать как делают все без копирования?
Код

ULONG CResourceList::LoadImage(ULONG _ID)
{
   char* FName;
   if(!GetImgPath(_ID, &FName)) 
      return 0;
   List[_ID].Destroy();
   List[_ID].Load(FName);
   return 1;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)