我正在学习C ++,现在我遇到了迭代器问题。这是我的情况:我这里有这个代码。
// std::list<Dragon*> dragons = cave.getDragons();
for (std::list<Dragon*>::iterator it = cave.getDragons().begin(); it != cave.getDragons().end(); it++){
os << std::endl << (*it)->getName();
}
它返回分段错误。这是我的列表和我的getDragons()方法:
std::list<Dragon*> dragons;
std::list<Dragon*> getDragons() const {return dragons;}
我的问题是......为什么我会像这样做一个Segmentation错误,但是如果我使用龙变量,这是评论,不是吗?谢谢!
答案 0 :(得分:1)
getDragons()
按值返回std::list
,因此每次拨打getDragons()
时,都会获得dragons
列表的副本。因此,您的for
循环将比较来自不同临时std::list
对象的迭代器,并将尝试取消引用无效迭代器。
你需要做更多这样的事情:
std::list<Dragon*> dragons = cave.getDragons();
for (std::list<Dragon*>::iterator it = dragons.begin(); it != dragons.end(); it++){
os << std::endl << (*it)->getName();
}
或者,如果您使用的是C ++ 11或更高版本,请改为使用for-range
循环:
for (Dragon *dragon : cave.getDragons()) {
os << std::endl << dragon->getName();
}
否则,您需要更改getDragons()
以通过引用返回std::list
:
const std::list<Dragon*>& getDragons() const {return dragons;}
然后你的原始for
代码会起作用,尽管它仍会在每次循环迭代时调用getDragons()
。最好将单个调用的结果缓存到本地变量:
const std::list<Dragon*> &dragons = cave.getDragons();
for (std::list<Dragon*>::const_iterator it = dragons.begin(); it != dragons.end(); it++){
os << std::endl << (*it)->getName();
}
或者,使用上面显示的相同的C ++ 11 for-range
循环。
答案 1 :(得分:0)
正如雷米解释的那样,您的潜在错误是列表副本的使用(这不仅容易出错,而且效率低下)。因此,正确的治疗方法是从不创建此类副本(Remy的答案仍然建议这样做)。为此,您的getDragons()
方法应返回参考。
struct Cave
{
/* ... */
std::list<const Dragon*> const&getDragons() const;
};
此外,您应尽可能使用auto
关键字(当然至少使用2011年标准)。
for(auto const&dragon : cave.getDragons())
os << std::endl << dragon.getName();