首页 > 解决方案 > 通过迭代器修改不反映

问题描述

我有一个幻灯片对象列表。每个 Slide 对象都有一个幻灯片元素向量,该幻灯片元素向量属于另一个类,例如具有成员的 ItemProperties

int 调整大小 int 旋转 int 移动

以及修改这些值的函数

void ResizeItem(int resize_val);
void RotateItem(int rotate_val);
void MoveItem(int move_val);

我正在迭代像这个“迭代部分”这样的对象列表

                        auto slidelist_ptr=VDECK.getSlideList(); /*returns list<Slide> by reference */
                        auto slidelist_itr=slidelist_ptr.begin(); /*returns iterator to beginning of Slide list*/
                        auto slidelemnts_itr=slidelist_itr->getSlideElemnt().begin(); /*returns iterator to beginning of slide list elements*/
                      
                            in1=_getch();
                            if(in1!=KEY_ARROW_1)
                            {
                                **VDECK.selectedSlideOperations((*slidelist_itr),in1-48);**
                                throw std::runtime_error("Operation success\n");
                            }
                        
                        ++slidelist_itr;
                        slidelemnts_itr=slidelist_itr->getSlideElemnt().begin();

在函数 selectedSlideOperations 中,我传递特定的幻灯片对象并将其作为函数中的引用,如下所示

 void Deck::selectedSlideOperations(Slide &obj,int choice)
 {
switch(choice)
{

case 5:
    ChangeSlideItemProperties(obj);
    break;

} }

在 ChangeSlideItemProperties 中,我再次将对象作为参考

   void Deck::ChangeSlideItemProperties(Slide &obj)
   {
         for(auto p=obj.getSlideElemnt().begin();p!=obj.getSlideElemnt().end();p++)
                    {
                        std::cout<<"before \n";
                        p->PrintItemProperties();
                        p->RotateItem(input);
                        std::cout<<"\nafter \n";
                        p->PrintItemProperties();
                    }
   }

在这里面,我正在迭代 Slide 对象的幻灯片元素(它是一个向量)并尝试修改向量中所有元素的成员“Rotate”的值。修改后,当我打印成员“之前”和“之后”时,成员旋转的值正确反映。但是修改后,当我退出此菜单并使用迭代打印幻灯片元素时,如“迭代部分”所示,所有成员的值为 0。

我对 C++ 相当陌生,请多多包涵……我不确定我在这里缺少什么。

编辑:对不起,我将幻灯片元素更改为列表而不是矢量,所以我只有列表,没有矢量

编辑 2:添加最小的可重现示例

using namespace std;
class Itemprop
{
    int Rotate;
public:
    Itemprop():Rotate{0}{}
    void Set_Rotate(int val)
    {
        Rotate = val;
    }
    int Get_Rotate()const
    {
        return Rotate;
    }
};

class Dummy
{
    public:
        Dummy();
        list<Itemprop>& getList(void)
        {
            return v;
        }
        virtual ~Dummy();

    protected:

    private:
        list<Itemprop> v;
};
int main()
{
    Dummy dobj;
    Itemprop iobj;
    iobj.Set_Rotate(1);
    dobj.getList().emplace_back(iobj);
    Itemprop iobj2;
    iobj2.Set_Rotate(2);
    dobj.getList().emplace_back(iobj2);
    for(auto p:dobj.getList())
    {
        cout<<"before\n";
        cout<<p.Get_Rotate()<<endl;
        p.Set_Rotate(3);
        cout<<"after\n";
        cout<<p.Get_Rotate()<<endl;

    }
    for(auto p:dobj.getList())
    {

        cout<<p.Get_Rotate()<<"<--new\n";
    }

输出是

before
1
after
3
before
2
after
3
1<--new
2<--new

标签: c++listc++11vectoriterator

解决方案


因为使用auto关键字的范围循环正在通过复制获取列表的元素(列表本身通过引用获取)。

快速修复也是通过引用来获取元素,例如:

for(auto& p:dobj.getList())

或者您可以使用std::list迭代器,就像您之前发布的代码一样:

    for(auto it = dobj.getList().begin(); it != dobj.getList().end(); it++)
    {
        cout<<"before\n";
        cout<<it->Get_Rotate()<<endl;
        it->Set_Rotate(3);
        cout<<"after\n";
        cout<<it->Get_Rotate()<<endl;
    }

推荐阅读