在迭代器中取消引用类指针函数 [英] Dereferencing a class pointer function in iterator
问题描述
我创建了一个指向名为Food的类的指针的矢量
vector< Food *>项目;
该类如下所示:
类Food{私人的:字符串名称;int月年份上市:无效的display(){cout<<名称<<-"<<月<<"/"<<年<<恩德尔}}
然后我创建了一个提示这些项目的功能
void hintInventory(vector< Food *>& items){字符串名称;int月年份做{cout<<输入商品名称:";getline(cin,名称);如果(名称!=退出"){cout<<输入到期月份:";cin>>月;cout<<输入到期年份:";cin>>年;cin.ignore();食物*食物=新食物;food-> setName(name);food-> setMonth(month);食物-> setYear(年);items.push_back(food);}}while(name!=退出);
我想遍历指针的向量并为所有项目调用display函数,但是我无法使用迭代器对其进行取消引用.
我如何能够成功地遍历这些指针并调用显示函数?
不幸的是
vector< Food *> :: iterator iter = items.begin();一会儿(iter< items.end()){cout<<* iter-> display()<<恩德尔}
结果:
错误:在"* iter"中请求成员"display".__gnu_cxx :: __ normal_iterator< _Iterator,_Container> :: operator->< Food **,std :: vector< Food *>>()",其指针类型为食物*"(也许您打算使用->"?)cout<<* iter-> display()<<恩德尔
谢谢!
操作员优先级有你.编译器将 * iter-> display()
解释为 *(iter-> display())
,因为->
具有优先于(将在 *
之前执行).一种更清晰的查看方法是 *((* iter).display())
- 将迭代器取消引用到
Food *
. - 尝试在
Food *
上调用显示.失败并导致编译器错误. - 取消对
display
的调用结果.
您需要在方括号中强制使用所需的执行顺序:(* iter)-> display()
- 将迭代器取消引用到
Food *
- 再次取消引用
Food
- 在
Food
上调用显示
修复此问题会导致问题2: display
不会返回可写入 cout
的任何内容.幸运的是, display
可以完成所有需要的打印.
while(iter< items.end()){(* iter)-> display();}
解决了这个问题,但是在惯用的C ++中,有一个更好的解决方案:重载<<
运算符.
Food
选择一个 friend
函数
类食品{私人的:字符串名称;int月年份上市:无效的display(){cout<<名称<<-"<<月<<"/"<<年<<恩德尔}朋友ostream&运算符<<(流& out,const Food&food){出<<food.name<<-"<<food.month<<"/"<<食物年退回}};
那么您可以
vector< Food *> :: iterator iter = items.begin();一会儿(iter< items.end()){cout<<** iter<<恩德尔}
或基于范围的for循环
<自动> <代码>(自动和项目:项目){cout<<*项目<<恩德尔}旁注:除了练习指针之外,还练习智能指针.您会发现它们更有用.
I have created a Vector of pointers to a class called 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) *
. A cleaner way to look at this is *((*iter).display())
- Dereference iterator to a
Food *
. - Attempt to invoke display on the
Food*
. Fails and results in the compiler error. - Dereference the result of the call to
display
.
You need to force the execution ordering you want with some brackets: (*iter)->display()
- Dereference iterator to a
Food *
- Dereference again to a
Food
- Invoke display on the
Food
Fixing this leads to problem 2: display
doesn't return anything that can be written to cout
. Fortunately, display
does all the printing that is required.
while (iter < items.end())
{
(*iter)->display();
}
resolves that problem, but in idiomatic C++ there is a better solution: overload the <<
operator.
Food
picks up a friend
function
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 (auto & item:items)
{
cout << *item << endl;
}
Side note: In addition to practicing pointers, practice Smart Pointers. You'll find them much more useful.
这篇关于在迭代器中取消引用类指针函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!