简体   繁体   English

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

[英]Dereferencing a class pointer function in iterator

I have created a Vector of pointers to a class called Food我创建了一个指向名为 Food 的类的指针向量

vector<Food*> items;

The class looks like the following:该类如下所示:

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

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

I then have created a function to prompt these items然后我创建了一个函数来提示这些项目

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);

I'd like to iterate through the vector of pointers and call the display function for all the items but I am unable to dereference them using iterators.我想遍历指针向量并为所有项目调用显示函数,但我无法使用迭代器取消对它们的引用。

How would I be able to sucessfully iterate through these pointers and call the display function?我怎样才能成功地遍历这些指针并调用显示函数?

Unfortunately,很遗憾,

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

Results in:结果是:

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;

Thank you!谢谢!

Operator Precedence has got you. 运算符优先级已为您服务。 *iter->display() is interpreted by the compiler as *(iter->display()) because -> has precedence over (will execute before) * . *iter->display()被编译器解释为*(iter->display())因为->优先于(将在之前执行) * A cleaner way to look at this is *((*iter).display())一个更清晰的方式来看待这个是*((*iter).display())

  1. Dereference iterator to a Food * .将迭代器解引用到Food *
  2. Attempt to invoke display on the Food* .尝试在Food*上调用 display 。 Fails and results in the compiler error.失败并导致编译器错误。
  3. Dereference the result of the call to display .取消引用调用display的结果。

You need to force the execution ordering you want with some brackets: (*iter)->display()您需要使用一些括号强制执行所需的执行顺序: (*iter)->display()

  1. Dereference iterator to a Food *将迭代器解引用到Food *
  2. Dereference again to a Food再次取消对Food引用
  3. Invoke display on the FoodFood上调用显示

Fixing this leads to problem 2: display doesn't return anything that can be written to cout .解决这个问题会导致问题 2: display不返回任何可以写入cout Fortunately, display does all the printing that is required.幸运的是, display完成了所有需要的打印。

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

resolves that problem, but in idiomatic C++ there is a better solution: overload the << operator.解决了这个问题,但在惯用的 C++ 中有一个更好的解决方案:重载<<运算符。

Food picks up a friend function Foodfriend功能

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;
    }
};

Then you can然后你可以

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

or with a range-based for loop或使用基于范围的 for 循环

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

Side note: In addition to practicing pointers, practice Smart Pointers .旁注:除了练习指针,还要练习智能指针 You'll find them much more useful.你会发现它们更有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM