如何正确地从 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&amp; 时,对迭代器的引用将无法编译。 来自 cplusplus.com:如果发生重新分配,所有与容器相关的迭代器、指针和引用都将失效。否则,只有结束迭代器无效,并且所有迭代器、指针和对元素的引用都保证继续引用它们在调用之前引用的相同元素。 你应该通过常量引用传递nameCurrency&amp; append(const wstring&amp; 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();

请注意,引用符号&amp; 已从函数签名中删除。

【讨论】:

非常感谢您的帮助。但在这种情况下,我更喜欢将元素向量更改为元素vector&lt;Currency *&gt; 上的指针向量,并手动为其分配内存。我认为在这种情况下这将是更正确的解决方案。

以上是关于如何正确地从 C++ 中的迭代器返回对对象的引用的主要内容,如果未能解决你的问题,请参考以下文章

迭代器知识整理

如何仅使用 C++ 中的迭代器正确迭代 3D 向量? [关闭]

返回 C++ 迭代器引用

返回 c++ 迭代器

如何正确遍历删除List中的元素(普通for循环增强for循环迭代器iteratorremoveIf+方法引用)

map高阶函数