我从指针

时间:2018-02-09 01:53:16

标签: 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;
}

WindowControl

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

2 个答案:

答案 0 :(得分:0)

您的问题是您要将局部变量的指针添加到m_controlPtrs

void AddControl(Control control)
{
    m_controlPtrs.push_back(&control);
}

在这里,您需要复制Control,然后将其地址添加到vector。函数返回的那一刻,你的对象超出范围,内存指向未初始化的垃圾。

您可能希望更新AddControl以获取Control&

@ShadowRanger raises a good point in the comments:我所提到的可能会无限期地解决您的问题,但您的设计仍然不是很好。只要您有Control的时间超过m_controlPtrs,您就会遇到同样的问题。你的代码现在很小,但最终可能会变成一个噩梦来修复。您可能应该更新m_controlPtrs以共享(或获取)Control的所有权,以便不会出现此问题。

最简单的方法是将m_controlPtrs声明为std::vector<std::shared_ptr<Control>>,但 应该考虑的事情。

答案 1 :(得分:0)

这里有一个问题:

  protected void configure(HttpSecurity http) throws Exception {

                http
                        .cors().and().**this will use corsConfigurationSource by** default.


    so lets define corsConfigurationSource

    // other criteria
    }

**so lets define corsConfigurationSource**

@Bean CorsConfigurationSource corsConfigurationSource() { 

CorsConfiguration configuration = new CorsConfiguration(); 

configuration.setAllowedOrigins(Arrays.asList("http://myufrontend.com")); 

configuration.setAllowedMethods(Arrays.asList("GET", "POST")); 

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

source.registerCorsConfiguration("/**", configuration);





 }

添加函数结束时销毁的参数void AddControl(Control control) { m_controls.insert_or_assign(control.GetId(), control); m_controlPtrs.push_back(&control); } 的地址。您好像要添加添加到control副本的地址,如下所示:

map

虽然这并不理想,因为如果您发送相同的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中返回的pait来修复:

insert_or_update

旁注:

在这种情况下返回引用而不是指针更为惯用:

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

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