将std :: list公开为只读

时间:2010-06-04 18:16:53

标签: c++ const stdlist

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

我得到'工作'atm的方式是返回列表的副本。这使我的班级“安全”,但当然没有阻止调用者修改他们的列表副本而没有获得正确的数据。

有更好的方法吗?

5 个答案:

答案 0 :(得分:15)

为什么不返回const std::list&

答案 1 :(得分:9)

不要暴露列表本身(根本不暴露),只需将const_iterator暴露给它的开头和结尾。请参阅cbegin()cend()以获取相关帮助...

答案 2 :(得分:4)

返回一个const引用:

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

或只返回const迭代器:

std::list<T>::const_iterator getListBegin() const;
std::list<T>::const_iterator getListEnd() const;

答案 3 :(得分: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任何东西。

答案 4 :(得分: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_;
};