如何正确地从 C++ 中的迭代器返回对对象的引用
Posted
技术标签:
【中文标题】如何正确地从 C++ 中的迭代器返回对对象的引用【英文标题】:How correct return reference to object from iterator in c++ 【发布时间】:2015-03-19 17:48:58 【问题描述】:在此类代码中使用对 std::vector
元素的引用时遇到问题:
class CurrencyList
public:
Currency &append(wstring name);
private:
vector<Currency> mCurrencyList;
;
Currency &CurrencyList::append(wstring name)
vector<Currency>::iterator currency = findByName(name);
if(currency != mCurrencyList.end())
return *currency;
mCurrencyList.push_back(Currency(name));
return *mCurrencyList.rbegin();
在这段代码中使用:
Currency& BaseVal = currencyList.append("AAA");
Currency& ProfitVal = currencyList.append("BBB");
return new CurrencyPair(name, BaseVal, ProfitVal);
当我在第二行收到 ProfitVal 时,BaseVal 的值已损坏。我认为 return *mCurrencyList.rbegin();给我参考迭代器,而不是向量的元素。然后它在第二次调用中改变了第一个值。在这种情况下我必须如何使用迭代器和引用?
【问题讨论】:
当您的返回类型为Currency&
时,对迭代器的引用将无法编译。
来自 cplusplus.com:如果发生重新分配,所有与容器相关的迭代器、指针和引用都将失效。否则,只有结束迭代器无效,并且所有迭代器、指针和对元素的引用都保证继续引用它们在调用之前引用的相同元素。
你应该通过常量引用传递name
:Currency& append(const wstring& name);
。
@chris 全部编译正确。这个来自良好编译项目的代码示例
@ThomasMatthews 我添加了 const 并且它的工作原理相同:BaseVal
的值在收到 ProfitVal
后被损坏
【参考方案1】:
最安全的解决方案是返回Currency
的副本:
Currency append(const wstring& name) // Note the return type.
vector<Currency>::iterator currency = findByName(name);
if(currency != mCurrencyList.end())
return *currency;
mCurrencyList.push_back(Currency(name));
return *mCurrencyList.rbegin();
请注意,引用符号&
已从函数签名中删除。
【讨论】:
非常感谢您的帮助。但在这种情况下,我更喜欢将元素向量更改为元素vector<Currency *>
上的指针向量,并手动为其分配内存。我认为在这种情况下这将是更正确的解决方案。以上是关于如何正确地从 C++ 中的迭代器返回对对象的引用的主要内容,如果未能解决你的问题,请参考以下文章
如何仅使用 C++ 中的迭代器正确迭代 3D 向量? [关闭]