将 SDL 曲面以及文件名放入地图中

发布于 2024-10-27 19:40:47 字数 418 浏览 2 评论 0 原文

我对在 C++ 中使用地图非常陌生,因此在将其用于 SDL 表面时遇到一些困难。这是我尝试过的(不起作用):

map <SDL_Surface*, char*> mSurfaceMap;

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

这个想法是将所有表面及其相应的图像文件放入地图中,以轻松初始化它们并对它们执行 IMG_Load() ,以及免费关闭程序时的它们。

如果这是一个不好的解决方案,请为我指出正确的方向。我首先想到制作两个数组,但我想尝试一下,因为我觉得这是一个更优雅的解决方案。如果解决方案没问题,我很想听听我在代码中做错了什么。

I'm very new to using maps in C++, so I am having some difficulties using it for my SDL surfaces. This is what I've tried (not working):

map <SDL_Surface*, char*> mSurfaceMap;

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

The idea is to put all surfaces and their corresponding image files in a map to easily initialize them and do IMG_Load() on them, as well as free them when closing the program.

If this is a bad solution for it, please point me in the right direction. I first thought of making two arrays, but I wanted to try this instead, as I felt it was a more elegant solution. If the solution is ok, I'd love to hear what I am doing wrong in the code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅浅淡淡 2024-11-03 19:40:47

这段代码对我有用。输出如预期:

#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;
}

This code works for me. Output is as expected:

#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;
}
神经暖 2024-11-03 19:40:47

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 > 可能足以满足您的需要。

或者,如果您已经将表面存储为成员(从变量名称假设),那么您可以将成员变量存储为 tr1::unique_ptr ,并且当包含的类被删除时,这样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;
};

std::map is great for looking up data by an ordered key, it is usually implemented as a balanced binary tree that gives O(log n) look-up time. If the look-up order doesn't matter then a std::hash_map will be a better choice with an O(1) look-up time.

The problem with using a pointer as your key in either container is that the they will index by the integer address of the pointer, not the value of what is pointed to.

std::string, however, has value semantics and implements the less-than operator which will let the container index by the value of the string.

You may also want to put your surface in a smart pointer for memory management purposes.

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)));

A couple of other thoughts...

If you don't need the look-up functionality, and are just using a container for housekeeping, then a simple std::vector<std::pair<std::string, SDL_Surface*> > would probably suffice for what you need.

Or, if you're storing the surfaces as members already (assuming from the variable name) then you could store the member variables as a tr1::unique_ptr<SDL_Surface> and when the containing class is deleted so will the SDL_Surface be deleted. For this to work however you need to provide a custom deallocator for the tr1::unique_ptr, that will teach it how to free an SDL_Surface*.

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

Then you would specify your members like this (a typedef makes it less verbose):

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;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文