【问题标题】:Undo/Redo using lists of shared_ptr使用 shared_ptr 列表撤消/重做
【发布时间】:2013-03-18 15:01:48
【问题描述】:

我正在尝试实现一个类似于绘画的绘图程序。我有两个包含 shared_ptrs 到 Shapes 的 std::lists。一个是“Undo”链表,另一个是“Redo”链表。在我对 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;
}

我不断得到 list iterator not deferencable....我只是想创建一个简单的撤消和重做

【问题讨论】:

  • draw.exe 当前正在执行吗?
  • 没有我的 for 循环它工作正常。是的,它是@hmjd ...我的迭代器使它无法编译
  • 如果.exe 正在运行,那么它是不可写的。停止.exe 然后重建。
  • 如何停止 .exe @hmjd。我忘了提。这使用 WTL。
  • 在任务管理器中找到它并终止它。

标签: c++ list pointers iterator shared-ptr


【解决方案1】:

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

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

来自list::end() 参考页面:

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

如果您想向后迭代,请使用reverse_iteratorsrbegin()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++)
{
}

【讨论】:

  • 如果我开始绘制超过 3 条线,它会摆脱所有三条线......我该如何解决这个问题?
  • 错误 C2440: 'initializing' : 无法从 'std::reverse_iterator<_ranit>' 转换为 'std::_List_iterator<_mylist>' 1> 1> [ 1> _RanIt=std:: _List_iterator<:_list_val>,std::allocator<:tr1::shared_ptr>>>> 1> ] 1> 和
  • 这就是我尝试反向操作时得到的结果
  • 这些是单独的问题,需要比您在 cmets 中明智地适应的更多细节才能回答。这个答案是正确的(记得改变迭代器的类型i如图)。
  • 这是有效的......但是如果我画两条线并撤消,两条线会被删除而不是一条
猜你喜欢
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2011-05-03
  • 1970-01-01
  • 2011-11-25
  • 2011-08-04
相关资源
最近更新 更多