在迭代器中取消引用类指针函数

时间:2018-11-22 03:14:50

标签: c++

我创建了一个指向Food类的指针的Vector

vector<Food*> items;

该类如下所示:

 class Food
 {
   private:
    string name;
    int month;
    int year;

   public:
    void display()
    {
      cout << name << " - " << month << "/" << year << endl;
    }
  }

然后我创建了一个提示这些项目的功能

void promptInventory(vector<Food*> &items)
{
   string name;
   int month;
   int year;

   do
   {
      cout << "Enter item name: ";
      getline(cin, name);

      if (name != "quit")
      {
         cout << "Enter expiration month: ";
         cin >> month;

         cout << "Enter expiration year: ";
         cin >> year;

         cin.ignore();

         Food * food = new Food;;

         food->setName(name);
         food->setMonth(month);
         food->setYear(year);

         items.push_back(food);
       }
     }
     while (name != "quit);

我想遍历指针的向量并为所有项目调用display函数,但是我无法使用迭代器对其进行取消引用。

我如何能够成功地遍历这些指针并调用显示函数?

不幸的是

vector<Food*>::iterator iter = items.begin();
while (iter < items.end())
{
  cout << *iter->display() << endl;
}

结果:

error: request for member ‘display’ in ‘* iter.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-><Food**, std::vector<Food*> >()’, which is of pointer type ‘Food*’ (maybe you meant to use ‘->’ ?)
   cout << *iter->display() << endl;

谢谢!

1 个答案:

答案 0 :(得分:2)

Operator Precedence吸引了您。 *iter->display()被编译器解释为*(iter->display()),因为->的优先级高于**((*iter).display())

是查看此问题的一种更干净的方法
  1. 取消对Food *的迭代器的引用。
  2. 尝试在Food*上调用显示。失败并导致编译器错误。
  3. 取消对display的调用结果。

您需要使用一些方括号来强制执行所需的执行顺序:(*iter)->display()

  1. 将迭代器解引用到Food *
  2. 再次取消引用Food
  3. 调用Food上的显示

修复此问题将导致问题2:display不会返回可写入cout的任何内容。幸运的是,display完成了所有需要的打印。

while (iter < items.end())
{
    (*iter)->display();
}

解决了这个问题,但是在惯用的C ++中,有一个更好的解决方案:重载<<运算符。

Food使用了friend函数

class Food
{
private:
    string name;
    int month;
    int year;

public:
    void display()
    {
      cout << name << " - " << month << "/" << year << endl;
    }
    friend ostream & operator<<(ostream & out, const Food & food)
    {
        out << food.name << " - " << food.month << "/" << food.year;
        return out;
    }
};

那么您可以

vector<Food*>::iterator iter = items.begin();
while (iter < items.end())
{
  cout << **iter << endl;
}

或带有基于范围的for循环

for (auto & item:items)
{
      cout << *item << endl;
}     

旁注:除了练习指针外,还练习Smart Pointers。您会发现它们更有用。