8

我有一个类,其中包含一个 std::list 等。我想公开这个列表,但只能以它包含的结构和数据是只读的方式公开,但仍然可以与迭代器一起使用。

我让它“工作”的方式是返回列表的副本。这让我的班级“安全”,但当然不会阻止调用者修改他们的列表副本并且没有获得正确的数据。

有没有更好的办法?

4

5 回答 5

17

为什么不返回 aconst std::list&呢?

于 2010-06-04T18:18:01.250 回答
9

与其暴露列表本身(根本),不如将const_iterators 暴露在它的开头和结尾。请参阅cbegin()cend()寻求帮助...

于 2010-06-04T18:18:42.250 回答
4

将数据成员暴露给外界存在依赖性问题。

如果您决定将属性更改为更好的东西(因为list是最后的容器),或者因为您有新的需求,那么您的所有客户都会受到影响,这很糟糕。

一个简单的替代方法是提供typedef

typedef std::list<Foo>::const_iterator const_iterator;

如果您的客户使用您的别名,那么只需重新编译代码即可。

另一种选择是创建自己的迭代器类(不是那么困难),它将嵌入实际的迭代器。

class const_iterator
{
public:

private:
  typedef std::list<Foo>::const_iterator base_type;
  base_type mBase;
};

您只需将所有操作转发给实际的迭代器,并且您的客户端(尽管如果您更改容器,他们将不得不重新编译)不会意外使用非别名类型。

然后,第三个解决方案类似于第一个,除了你抽象类型......虽然它非常低效(对于列表),所以我不会真的建议它:迭代器应该很便宜,你不要'什么都不想new

于 2010-06-04T18:33:55.557 回答
4

返回一个常量引用:

const std::list<T>& getList() const;

或者只返回 const 迭代器:

std::list<T>::const_iterator getListBegin() const;
std::list<T>::const_iterator getListEnd() const;
于 2010-06-04T18:18:10.547 回答
3
class foo {
  private:
     typedef std::list<bar> bar_cont_t;

  public:
     typedef bar_const_t::const_iterator bar_const_iterator;

     bar_const_iterator bar_begin() const {return bar_data_.begin();}
     bar_const_iterator bar_end  () const {return bar_data_.end  ();}

     // whatever else

  private:
     bar_cont_t bar_data_;
};
于 2010-06-04T18:26:59.743 回答