使用引用时向量的意外行为

时间:2018-04-23 10:02:42

标签: c++ sdl

我正在创建一个通常使用事件的SDL游戏,我总是遇到这种奇怪的向量行为,我认为它是由于使用了引用,因为我更有可能通过参考

game.cpp

Events e;
SDL_Event sdle;

// Loop until someone hits the main switch
while (SWITCH)
{
    // Poll events
    while (SDL_PollEvent(&sdle) != 0)
    {
        // Execute event callbacks
        e.exec_events(sdle); // DEBUG BREAKPOINT HERE
    }
}

events.h

struct Listener
{
    SDL_Rect* rect;

    std::function<void()> on_clicked;
    std::function<void()> on_mouse_over;
    std::function<void()> on_mouse_out;
};

Listener l;
SDL_Rect rect = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
l.rect = &rect;
l.on_mouse_over = []() {
    Game::showerrmsg("Hovered!", "Hovered!");
};
e.add_listener(&l);

events.cpp

std::vector<Listener*> listeners;

// I've passed the sdle here
void Events::exec_events(SDL_Event& e)
{
    analyze(e);
}

// from exec_events, sdle will be passed here
void Events::analyze(SDL_Event& e)
{
    // The problem starts here after hitting the above line
    switch (e.type)
    {
    case SDL_MOUSEMOTION:
        currentEvent = MOUSE_MOVE;
        break;
    case SDL_MOUSEBUTTONDOWN:
        currentEvent = MOUSE_CLICK;
        break;
    case SDL_MOUSEBUTTONUP:
        currentEvent = MOUSE_CLICKED;
        break;
    }

    // .......
}

DEBUG POINT:

在点击switch (e.type)之前

normal 点击switch (e.type)

unexpected

看起来对象已被解除分配。我不知道发生了什么

我尝试在堆中分配监听器向量但仍然遇到了同样的问题。最后,我使用指针传递引用并且它工作,它没有弄乱向量。我无法解释这一点,并最终问自己,指针比引用更好(我知道指针很强大),引用是否比指针更危险?

3 个答案:

答案 0 :(得分:1)

引用向量不起作用。向量的内容应为assignable,引用不是。

所以你尝试使用指针克服了这个问题,但也存在问题。如果指针在别处被解除分配会发生什么?考虑使用智能指针

  

引用比指针更危险吗?

<强>更新

原始指针很危险。这就是为什么你应该考虑使用Smart Pointers

但我不建议在堆上分配你的矢量。你的应用程序是多线程的吗?它是线程安全的吗?

答案 1 :(得分:0)

是比指针更危险的引用吗?

不,在一些过度简化中,这些是相同的,指针可以更改,而引用无法更改。

还有一些其他差异,因为使用nullptr作为引用是未定义的行为。

还没有指定如何表示引用。所以这不能用于二进制兼容。

如果参考足够,我没有理由不使用它。

答案 2 :(得分:0)

我通过将Listeners*替换为Listeners

来克服这个问题
typedef std::map<str, Listener> listeners_map;
listeners_map listeners;