Размещение поверхностей SDL на карте вместе с именами файлов - PullRequest
0 голосов
/ 30 марта 2011

Я очень плохо знаком с использованием карт в C ++, поэтому у меня возникли некоторые трудности с использованием его для моих поверхностей SDL.Это то, что я пробовал (не работает):

map <SDL_Surface*, char*> mSurfaceMap;

mSurfaceMap.insert(pair<SDL_Surface*, char*>(m_poSurfaceTest, "..//..//gfx//testImage.png"));

Идея состоит в том, чтобы поместить все поверхности и соответствующие им файлы изображений в карту, чтобы легко их инициализировать и также выполнить IMG_Load() для них.как освободить их при закрытии программы.

Если это плохое решение, пожалуйста, укажите мне правильное направление.Сначала я подумал о создании двух массивов, но я хотел попробовать это вместо этого, так как чувствовал, что это более элегантное решение.Если решение в порядке, я хотел бы услышать, что я делаю неправильно в коде.

Ответы [ 2 ]

0 голосов
/ 30 марта 2011

Этот код работает для меня. Вывод соответствует ожидаемому:

#include <map>
#include <stdio.h>

using std::map;
using std::pair;

struct Custom
{
    int val;
    Custom() {val=0;}
};

int main(int argC,char* argV[]) 
{
    map<Custom*,char*> mMap;
    Custom* test = new Custom;
    mMap.insert(pair<Custom*,char*>(test,"Test"));
    printf("%s\n",mMap[test]);
    return 0;
}
0 голосов
/ 30 марта 2011

std::map отлично подходит для поиска данных по упорядоченному ключу, обычно он реализован в виде сбалансированного двоичного дерева, которое дает O (log n) время поиска.Если порядок поиска не имеет значения, тогда std::hash_map будет лучшим выбором с временем поиска O (1).

Проблема с использованием указателя в качестве ключа в любом контейнеречто они будут индексировать по целочисленному адресу указателя, а не по значению того, на что указано.

std::string, однако, имеет семантику значений и реализует оператор «меньше», который позволяет индексу контейнерапо значению строки.

Возможно, вы захотите поместить свою поверхность в интеллектуальный указатель для целей управления памятью.

typedef std::tr1::shared_ptr<SDL_Surface> surface_pointer;
typedef pair<std::string, surface_pointer > surface_pair;

std::map<std::string, surface_pointer > mSurfaceMap;

mSurfaceMap.insert(surface_pair("..//..//gfx//testImage.png", surface_pointer(m_poSurfaceTest)));

Пара других мыслей ...

Если вам не нужны функции поиска и вы просто используете контейнер для ведения домашнего хозяйства, тогда простого std::vector<std::pair<std::string, SDL_Surface*> >, вероятно, будет достаточно для того, что вам нужно.

Или, если высохраняя поверхности уже как члены (исходя из имени переменной), вы можете сохранить переменные-члены как tr1::unique_ptr<SDL_Surface>, а когда содержащий класс удаляется, так и SDL_Surface будет удален.Однако для того, чтобы это работало, вам нужно предоставить специальный освобождающий модуль для tr1::unique_ptr, который научит его, как освободить SDL_Surface*.

struct SdlSurfaceDeleter {
    void operator() (SDL_Surface*& surface) {
        if (surface) {
            SDL_FreeSurface(surface);
            surface = NULL;
        }
    }
};

Затем вы должны указать своих членов следующим образом (typedef)делает его менее многословным):

typedef std::tr1::unique_ptr<SDL_Surface, SdlSurfaceDeleter> surface_ptr;

class MyClass {
public:
    MyClass(const std::string& path)
        : m_poSurfaceTest(IMG_Load(path.c_str()) { }

    surface_ptr m_poSurfaceTest;
};
...