【问题标题】:How do I access objects in a linked-list in C++如何在 C++ 中访问链表中的对象
【发布时间】:2011-09-27 13:00:00
【问题描述】:

我非常习惯使用数组和向量,但现在我正在使用一些 STD::lists,以及我制作的自定义列表类。

假设我有一个简单的类,Stock。

//stock.h
class Stock{
public:
    Stock(); //default constructor
    Stock(string, double); //overloaded constructor
    void setSymbol(string); //sets stock symbol
    void setPrice(double);
    string getSymbol();
    double getPrice();        
private:
    string symbol;
    double price;
};

现在在一个单独的文件中,我有我的 int main 来测试。

#include "stock.h"
#include <list>

int main(){
    list<Stock> portfolio;

    Stock Google("GOOG", 500);
    Stock Apple("APPL", 300);
    Stock Chipotle("CMG", 200);

    portfolio.push_back(Google);
    portfolio.push_back(Apple);
    portfolio.push_back(Chipotle);
}

现在,如果这是一个向量或数组,我不会有任何问题,我只是完全失去了与以下等效的链表:

for(int i=0; i <portfolio.size(); i++){
    portfolio[i].getSymbol();
    portfolio[i].getPrice();
 }

或者类似的东西...我没有关于链接列表的讲座/培训,所以我真的在尽我所能地自学——但我被困在基本的操作上。我现在正在使用 STL::list,但也确实在尝试创建自己的课程。

【问题讨论】:

  • 你真的应该使用你的列表类的iterator。不幸的是,我现在懒得告诉你怎么做,但请查一下!

标签: c++ object linked-list


【解决方案1】:
for(int i= portfolio.begin(); i <portfolio.size(); i++)

如果这对 std::vector 有效,那只是纯属偶然。我不知道这对向量有什么作用。

std::any_stl_container::begin() 返回一个称为“迭代器”的对象。具体来说,std::any_stl_container::iterator 类型的对象。迭代器有点像通用指针:它指向 STL 容器中的元素。

begin 返回的迭代器是引用列表中第一个元素的迭代器。您可以像指针一样移动迭代器。例如:

std::list<Stock> portfolio;
...
std::list<Stock>::iterator currElem = portfolio.begin();
++currElem; //Now points to the second element in the list.
Stock &secondStock = *currElem;

为了遍历列表中的所有元素,您需要两个迭代器:第一个迭代器和列表中最后一个元素之后元素的迭代器。幸运的是,这是由 std::any_stl_container::end() 函数返回的。所以,你的循环应该是这样的:

typedef std::list<Stock>::iterator StockIt;
for(StockIt i = portfolio.begin(); i != portfolio.end(); ++i) /* Prefer pre-increment with iterators */
{
    i->getSymbol();
    i->getPrice();
}

这适用于任何常用的 STL 容器。

【讨论】:

  • 原始代码当然不会编译...我更正了那个错字(他/她显然使用 0 作为开始而不是 portfolio.begin())并将 pushback 更正为 push_back
  • @Nicol-Bolas 谢谢。似乎我很难考虑指针/迭代器而不是直接访问元素。我刚把我的 std::vector 放在一起,代码可能不起作用。
【解决方案2】:

您还拥有begin()end() 的迭代器std::list

for (list<stock>::iterator it = portfolio.begin() ; it != portfolio.end(); it++)
{
  // use 'it' to access the current element (i.e. *it)
}

【讨论】:

    【解决方案3】:

    你必须使用iterators。每个 STL 容器都有它们,甚至是向量。它们的行为类似于指针;它们可以用 * 或 -> 取消引用,可以递增,可以比较。

    for( list<Stock>::iterator it = portfolio.begin(); it != portfolio.end(); it++ ){
        it->getSymbol();
        it->getPrice();
    }
    

    【讨论】:

      【解决方案4】:

      std::list 类型的对象在尝试计算其长度时效率非常低,因为这样的操作将具有线性时间。

      因此,对于列表,您不能将迭代器与 &lt;&gt; 运算符进行比较。尝试使用运算符 [] 获取第 n 个元素也是不明智的。

      此外,您不应混合使用分别是迭代器和整数的 begin()size()

      迭代std::list 的正确方法是使用一对迭代器begin()end() 并递增你的迭代器直到它到达end()

      所以,有两种方法:

      for(std::list<stock>::const_iterator i = my_list.cbegin(); i != my_list.cend(); ++i)
      {
          // access a “const stock &” object via *i
      }
      

      for(std.:list<stock>::iterator i = my_list.begin(); i != my_list.end(); ++i)
      {
          // access a “stock &” object via *i
      }
      

      【讨论】:

        猜你喜欢
        • 2016-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 1970-01-01
        • 2017-12-29
        相关资源
        最近更新 更多