撤销/重做使用列表的shared_ptr

Undo/Redo using lists of shared_ptr

本文关键字:shared ptr 列表 重做 撤销      更新时间:2023-10-16

我想实现一个绘图程序有点像油漆。我有两个std::列表,其中包含shared_ptrs到形状。一个是"撤销"链表,另一个是"重做"链表。在我调用Shape shared_ptr上的reset之前,通过push_back将shared_ptr添加到Undo链表中。

LRESULT CDrawView::OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
   int xPos= GET_X_LPARAM(lParam);
   int yPos = GET_Y_LPARAM(lParam);
   end.X = xPos;
   end.Y = yPos;
   m_shape->setEnd(xPos,yPos);
   m_shape->Draw(m_GraphicsImage);
   Undo.push_back(m_shape);
   RedrawWindow();
return 0;
}

当给出撤消命令时,我抓住撤消链表后面的shared_ptr并将其移动到重做链表。然后,清除m_GraphicsImage为白色,最后尝试遍历Undo列表,重新绘制所有内容。

LRESULT CMainFrame::OnUndo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   m_view.Redo.push_back(m_view.Undo.back()); //gets the first element that was Undo
   m_view.m_GraphicsImage.Clear(255); //Clears the board
   for(std::list<std::shared_ptr<Shape>>::iterator it = m_view.Undo.end(); it!=m_view.Undo.begin() ; it--)
   {
     it->get()->Draw(m_view.m_GraphicsImage);
   }
return 0;
}

我一直得到列表迭代器不可延迟....我只是想创建一个简单的撤销和重做

end()迭代器解引用是非法的,这是在这个循环的第一次迭代中发生的:

for(std::list<std::shared_ptr<Shape>>::iterator it = m_view.Undo.end();

摘自list::end()参考页:

返回一个迭代器,指向容器最后一个元素后面的元素。此元素充当占位符;试图访问它会导致未定义的行为。

使用reverse_iterators, rbegin()rend(),如果您希望向后迭代:

for (std::list<std::shared_ptr<Shape>>::reverse_iterator i(l.rbegin());
    i != l.rend();
    i++)
{
}

当你有c++11的特性可用时(std::shared_ptr),你可以使用auto来推断iterator类型,而不是显式地输入它:

for (auto i(l.rbegin()); i != l.rend(); i++)
{
}