如何在C++中访问链接列表中的对象

How do I access objects in a linked-list in C++

本文关键字:列表 对象 链接 访问 C++      更新时间:2023-10-16

我非常习惯于处理数组和向量,但现在我正在处理一些STD::列表,以及我创建的自定义列表类。

假设我有一节简单的课,斯托克。

//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,但实际上也在尝试创建自己的类。

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容器。

对于std::list也有begin()end()迭代器:

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

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

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

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

因此,对于列表,不能将迭代器与<>运算符进行比较。尝试使用运算符[]来获得第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
}