【问题标题】:Vector iterators向量迭代器
【发布时间】:2011-11-15 19:31:22
【问题描述】:

我有以下代码。

vector<IRD>* irds = myotherobj->getIRDs();//gets a pointer to the vector<IRD>
for(vector<IRD>::iterator it = irds->begin(); it < irds->end(); it++)
    {
        IRD* ird = dynamic_cast<IRD*>(it);
        ird->doSomething();
        //this works (*it).doSomething();

    }

这似乎失败了...我只想在不使用 (*it) 的情况下获取指向向量中每个元素的指针。全部结束。

  1. 如何获得指向对象的指针?
  2. 当我迭代矢量指针 irds 时,我究竟在迭代什么?它是每个元素的副本,还是当我说 (*it).doSomething() 时,我正在使用向量中的实际对象,

【问题讨论】:

    标签: c++ vector iterator


    【解决方案1】:

    您需要使用 != 和迭代器来测试结束,而不是像使用指针那样使用 &lt;operator&lt; 恰好可以与 vector 迭代器一起使用,但是如果您切换容器(切换到像 list 这样的容器),您的代码将不再编译,因此通常使用 != 比较好。

    另外,迭代器不是它指向的类型,所以不要尝试强制转换它。您可以在迭代器上使用重载的operator-&gt;

    vector<IRD>* irds = myotherobj->getIRDs();//gets a pointer to the vector<IRD>
    for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
    {
        it->dosomething();
    }
    

    【讨论】:

      【解决方案2】:

      首先考虑您是否真的需要一个指向元素的指针,或者您是否只是想使用迭代器但又避免使用它们。看起来您正在尝试用 C++ 编写 C 代码,而不是编写 C++ 代码。在您给出的示例中,似乎与其转换为指针然后使用该指针,不如直接使用迭代器? it-&gt;doSomething() 而不是 ird-&gt;doSomething()

      如果您认为需要保存该指针以供以后在完成一些工作后在向量上使用,那可能很危险。向量迭代器 指向向量中元素的指针都可以失效,这意味着它们不再指向向量,因此您基本上是在释放内存后尝试使用内存,这是一件危险的事情.可能使迭代器无效的一个常见示例是添加新元素。我陷入了试图存储迭代器的混乱中,我做了很多工作来让它工作,包括编写一个“re_validate_iterator()”函数。最终,事实证明我的解决方案非常混乱,甚至无法在所有情况下都有效,而且无法扩展。

      尝试存储向量位置的解决方案是将其存储为偏移量。一些整数,指示元素在向量中的位置。如果您需要使用迭代器,则可以使用myvector.begin() + index 访问它,或者如果您想要通过边界检查引用元素本身,则可以使用myvector.at (index) 访问它,或者如果您不需要边界检查,则只需myvector [index]

      【讨论】:

        【解决方案3】:

        通常的习惯用法是 &*it 来获取指针。动态转换与它无关。

        【讨论】:

          【解决方案4】:

          取消引用迭代器以获取对底层对象的引用。

          vector<IRD>* irds = myotherobj->getIRDs();
          for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
          {
              IRD& ird = *it;
              ird.doSomething();
              // alternatively, it->doSomething();
          }
          

          【讨论】:

            【解决方案5】:

            当我遍历向量指针 irds 时,我到底在遍历什么?它是每个元素的副本,还是当我说 (*it).doSomething() 时,我正在使用向量中的实际对象,

            当您迭代一个向量时,您使用的是对象本身,而不是它的副本。

            【讨论】:

              【解决方案6】:

              您可以通过执行&amp;*it 从迭代器获取指针。您将获得指向存储在向量中的实际 IRD 对象的指针。您可以通过指针修改对象,修改将“粘”:它将持续存在于向量中。

              但是,由于您的向量包含实际对象(不是指向对象的指针),我在dynamic_cast 中看不到任何意义。指针类型为IRD *,指向IRD对象。

              取消引用的迭代器可能引用副本(或更准确地说,代理对象)的唯一情况是vector&lt;bool&gt;,它可能被实现为位向量。

              【讨论】:

                【解决方案7】:

                为什么要获取指针?

                使用参考:

                for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
                {
                    IRD & ird = *it;
                    ird.doSomething();
                }
                

                或者:

                for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
                {
                    it->doSomething();
                }
                

                另外,正如大家所说,比较迭代器时使用!=,而不是&lt;。虽然它可以在这种情况下工作,但如果您使用不同的容器(这就是迭代器的用途:抽象底层容器),它将停止工作。

                【讨论】:

                • 感谢回答了两个问题并修复了一个错误!来自 C...总是忘记引用类型...它们在某种意义上就像一个抽象指针吗?
                • @user623879 迭代器被设计成“看起来像”一个指针。事实上,指针可以看作是迭代器的一种特例(它实际上是原始数组的迭代器类型)。
                猜你喜欢
                • 2017-08-29
                • 2018-07-09
                • 2013-12-16
                • 1970-01-01
                • 1970-01-01
                • 2013-02-07
                • 1970-01-01
                • 2020-11-06
                相关资源
                最近更新 更多