c++ - 我从指针得到一个未初始化的对象

标签 c++ pointers sfml

所以我在获取使用 SFML 形状的指针时遇到了一些麻烦。我不确定它是否与 SFML 有关,或者我是否做错了什么。

在 Draw() 中,x(a ControlWindow) 不包含有效值,它仅显示“???”,如此处所示。但是 m_controls(map) 包含控制对象的正确值。

我是 C++ 的新手,所以非常感谢任何帮助。

异常

Exception thrown at 0x60B26EE5 (sfml-graphics-2.dll) in OokiiUI.exe: 0xC0000005: Access violation reading location 0x00000000.

主要内容

vector<WindowControl> windowControls;

void Draw ();

int main ()
{
    RectangleShape rect(Vector2f(120,120));
    WindowControl windowControl(nullptr,0);
    Control testControl(&windowControl,1);

    testControl.SetShape(&rect);

    windowControl.AddControl(testControl);
    windowControls.push_back(windowControl);


    return 0;
}

窗口控件

class WindowControl : Control
{
public:
    WindowControl ( WindowControl * windowControl, uint64_t uint64 )
        : Control ( windowControl, uint64 )
    {
    }

    void AddControl(Control control)
    {
        m_controls.insert_or_assign(control.GetId(), control);
        m_controlPtrs.push_back(&control);
    }

    vector<Control*>* GetControls()
    {
        return &m_controlPtrs;
    }

private:
    map<uint64_t, Control> m_controls;
    vector<Control*> m_controlPtrs;
};

绘制

for (auto x : windowControls)
{
    vector<Control*> *controlPtrs = x.GetControls();
    window->draw(x.GetControl(0)->GetShape());
}

最佳答案

这里有个问题:

void AddControl(Control control)
{
    m_controls.insert_or_assign(control.GetId(), control);
    m_controlPtrs.push_back(&control);
}

您添加参数 control 的地址,该地址在函数结束时被销毁。看起来您想像这样添加您添加到 mapcopy 的地址:

void AddControl(Control control)
{
    m_controls.insert_or_assign(control.GetId(), control);
    // don't use the parameter here, use the copy you put in the map
    m_controlPtrs.push_back(&m_controls[control.GetId()]); 
}

尽管这并不理想,因为如果您发送相同的 control 两次,它只会在 map (已更新)中出现 一次两次 在指针 vector 中。您可以使用 insert_or_update 返回的 pait 来解决这个问题:

void AddControl(Control control)
{
    auto [iter, was_inserted] = m_controls.insert_or_assign(control.GetId(), control);

    // only add to vector if it was not in the map before
    if(was_inserted)
        m_controlPtrs.push_back(&iter->second);
}

旁注:

在这种情况下返回一个引用比返回一个指针更为惯用:

vector<Control*>& GetControls()
{
    return m_controlPtrs;
}

这也破坏了封装,因此可能值得考虑如何避免如此直接地访问对象的内部。

关于c++ - 我从指针得到一个未初始化的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48697611/

相关文章:

c++ - 计算多边形在网格中旋转后所占的位置

c++ - C 到 C++ 指针数组的转换问题

c - 如何使用指针更改字符串中的字符?

链接 sfml-audio 时的 C++ undefined reference

c++ - QFile打开文件写入失败

c++ - new不分配内存?

c++使用字符串的动态数组不接受字符串

c++ - 用于空安全指针访问的 C/C++ 宏

C++ SFML 编译错误 sf::NonCopyable::NonCopyable(const sf::NonCopyable&) is private

c++ - 程序因对象 vector 而崩溃