0

ペイントのような描画プログラムを実装しようとしています。シェイプへの shared_ptrs を含む 2 つの std::lists があります。1 つは「元に戻す」リンク リストで、もう 1 つは「やり直し」用です。Shape shared_ptr でリセットを呼び出す前に、push_back を介して undo リンク リストに shared_ptr を追加します。

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

Undo コマンドが与えられると、Undo リンク リストの後ろにある shared_ptr を取得し、Redo リンク リストに移動します。次に、m_GraphicsImage を白にクリアし、最後に元に戻すリストを反復処理して、すべてを再描画します。

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

リストイテレータが deferencable ではありません....単純な取り消しとやり直しを作成しようとしています

4

1 に答える 1

2

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++)
{
}
于 2013-03-28T08:59:26.707 に答える