类设计问题 - 如何提供对类成员容器的只读访问

nab*_*lke 7 c++

在我的日常工作中,我经常发现自己编写类似于这个简化示例中的类:

class CGarage
{
public:
    CGarage();
    ~CGarage();
    typedef std::vector<Car> CarCollection;

private:
    CarCollection m_Cars;
};
Run Code Online (Sandbox Code Playgroud)

我希望CGarage的用户只能访问CarCollection.为了实现这一目标,这些是一些不太令人满意的常见解决方案:

解决方案1

class CGarage
{
    Car GetCar(CarCollection::size_type index) const;
    CarCollection::size_type CarCount() const;
};
Run Code Online (Sandbox Code Playgroud)

主要缺点:

  • 缺乏迭代器,我不能在汽车上使用STL算法(例如for_each(...))

解决方案2

class CGarage
{
    CarCollection::const_iterator CarBegin() const;
    CarCollection::const_iterator CarEnd() const;
    CarCollection::size_type CarCount() const;
};
Run Code Online (Sandbox Code Playgroud)

主要缺点:

  • 如果需要支持其他迭代器类型(it,reverse_it),那么很多样板代码.

解决方案3

class CGarage
{
    const CarCollection GetCars() const;
};
Run Code Online (Sandbox Code Playgroud)

主要缺点:

  • 按值返回时复制CarCollection的成本
  • 类的用户已知的实现细节(例如,在不更改破坏用户代码的情况下无法更改为std :: list)

解决方案4

class CGarage
{
    const CarCollection& GetCars() const;
};
Run Code Online (Sandbox Code Playgroud)

主要缺点:

  • CarCollection参考的生命周期与CGarage的生命周期有关
  • 类的用户已知的实现细节

问题

您如何提供对CarCollection的只读访问权限?

如果CarCollection是一个带Car指针的向量,你的解决方案会改变吗?

如果您允许对集合进行读写访问,那么将集合公开是否可以接受?

谢谢你的建议

Pet*_*der 5

您如何提供对CarCollection的只读访问权限?

我不明白解决方案4有什么问题.对于CGarage的用户来说,显而易见的是,对其汽车收藏的参考与车库的使用寿命有关.如果他们需要汽车收藏品比车库更长,那么他们总是可以随心所欲地复制.

或者,让CGarage持有shared_ptr汽车收藏并返回,但我不推荐它.

如果CarCollection是一个带Car指针的向量,你的解决方案会改变吗?

对于拥有对象的集合(即引用类型),最好使用不同的容器.该std::容器都被设计为值类型,并且不处理引用类型非常好(尤其是数量不同).对于这些,使用Boost的ptr_vector之类的东西.

如果您允许对集合进行读写访问,那么将集合公开是否可以接受?

取决于您的具体情况.集合的语义可能会改变吗?如果没有,那么你可以安全地公开(例如std::pair).我不建议您为域特定问题执行此操作.