我从指针中得到一个非初始化的对象
I get an uninitialized object from a pointer
所以我有一些麻烦,让指针与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());
}
这里有一个问题:
void AddControl(Control control)
{
m_controls.insert_or_assign(control.GetId(), control);
m_controlPtrs.push_back(&control);
}
您添加函数结束时被破坏的参数control
的地址。看起来您想添加 copy 的地址,然后将其添加到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
,但它将仅在地图中出现一次(更新(,但在Pointers的向量中两次。您可以使用 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);
}
旁注:
在这种情况下返回参考而不是指针是更惯用的:
vector<Control*>& GetControls()
{
return m_controlPtrs;
}
这也打破了封装,因此可能值得考虑如何避免直接访问对象的内部。
您的问题是您将本地变量的指针添加到m_controlPtrs
:
void AddControl(Control control)
{
m_controlPtrs.push_back(&control);
}
在这里,您可以将Control
的副本添加到vector
中。函数返回的那一刻,您的对象就脱离了范围,而内存则指向非初始化的垃圾。
您可能想更新AddControl
以服用Control&
。
@shadowranger在评论中提出了一个很好的观点:我提到的内容可能会无限期地解决您的问题,但您的设计并不是很棒。每当您有一个Control
时,它不会超过m_controlPtrs
,您就会遇到同样的问题。您的代码现在很小,但最终可能会变成一场噩梦以修复。您可能应该更新m_controlPtrs
以共享(或获取(Control
的所有权,因此不会发生此问题。
最简单的方法是将m_controlPtrs
称为std::vector<std::shared_ptr<Control>>
,但这是您应该考虑的东西。
- 构造函数在退出函数时无法初始化一个参数
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- C++:将初始化的对象传递给另一个类的构造函数;需要不必要的构造函数吗?
- 将另一个类的对象传递到当前类C++的构造函数中(不是成员初始化)
- 'auto *x = new some_struct{};"是一个未初始化的变量?
- 有没有办法使用该类的构造函数初始化另一个类的私有部分内的对象数组?
- 初始化类中的指针数组,并在另一个类中检索它
- C++,每个循环初始化一个新的静态变量
- 初始化一个由 p 指向的新 INTSTK,它最多可以存储 m 个
- 如何初始化一个标准::字符串数组?
- 我们如何初始化一个C++中所有值为 0 的向量
- C++ 警告:在一个声明中将截断从双精度初始化为浮点数,但在另一个声明中则不初始化
- 从C++调用 Python 类方法,如果给定一个初始化的类作为 PyObject
- C++11使variadic构造函数了解一个初始化列表的初始化列表
- 静态变量已用另一个初始化
- 与可以一个从另一个初始化的类的循环依赖关系
- 另一个初始化静态 C++ 类成员