如果我从 getter 创建迭代器,则程序中止

Flo*_*ian 0 c++ getter iterator

这是一种奇怪的行为,我不明白我有。

我有一个带有列表的类 a 和一个吸气剂:

class A
{
  private:
   std::list<OtherClass *> l;
  public:
   std::list<OtherClass *> getL()
   {
     return l;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果我做类似的事情:

A inst;
std::list<OtherClass *>::iterator itB = inst.getL().begin();
std::list<OtherClass *>::iterator itE = inst.getL().end();
for (; itB != itE; ++itB) // Instant ABORT !
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

A inst;
std::list<OtherClass *> l = inst.getL();
std::list<OtherClass *>::iterator itB = l.begin();
std::list<OtherClass *>::iterator itE = l.end();
for (; itB != itE; ++itB) // It works now !
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么会发生这种情况吗?为什么我必须通过这样的临时变量才能不中止?先感谢您 !

lee*_*mes 5

虽然所有其他答案都建议将可修改的引用作为返回值,但我会将它们设为const

const std::list<OtherClass *> &getL() const;
Run Code Online (Sandbox Code Playgroud)

此外,我将函数本身设为 const,这意味着它不会修改对象本身。因此,您有一个正确的getter 方法(它既不应修改对象也不应返回可修改的引用)。

您可能想要引入这样一个 getter 函数的第二个版本,它可以修改属性(如果我们不想隐藏一些在属性更改时需要执行的代码,比如更新一些相关的东西):

std::list<OtherClass *> &getL();
Run Code Online (Sandbox Code Playgroud)

但是,正如已经指出的,在某些情况下,此版本不是您想要的。如果您必须在 setter 方法中执行某些操作,则您不想公开该属性的可修改引用。调用者必须如上所示调用 getter,修改值并调用 setter。但是,对于列表、向量、地图等大数据结构,这可能会很慢,因此您可能需要引入单个元素设置器,例如:setLAt(int index, OtherClass *value);