我有一个类名为粒子,其具有一个std ::设置为成员。类看起来像这样:

class Particle {
private:
    std::set<vtkIdType> cells;
    std::set<vtkIdType>::iterator ipc;

public:

    Particle() {};

    enum state {EXISTS = -1, SUCCESS = 0, ERROR = 1};

    state addCell(const vtkIdType cell);

    int numCells() { return static_cast<int>(cells.size()); }

    vtkIdType getFirstCell() { return (*(ipc = this->cells.begin()));}
    vtkIdType getNextCell() { return *(++ipc); }
    vtkIdType hasNextCell() { ++ipc; if (ipc == this->cells.end()) return false; --ipc; return true; }

    std::string getOutput();
};

我很不满getFirstCell()getNextCell()尤其是hasNextCell(),他们的存在是因为我不想暴露自己设定。我不得不通过++ipc--ipc使用方式,因为if((ipc+1) == this->cells.end())给出了一个编译器错误,IPC + 1似乎是问题。

什么是封装了一组和访问它的好办法?此外,有没有摆脱getFirstCell()功能的一个很好的方式?

预先感谢。

编辑:我发布的代码只是类结构的一个例子。 “真正的”类包含更多组和其它数据是不为这个问题(I假定)。

这重要
有帮助吗?

解决方案

我不知道为什么你不想暴露组本身,但如果是因为要确保集的内容不能外class Particle改变只是返回const迭代这使得集“读 - 只有”,例如

typedef std::set<vtkIdType>::const_iterator CellIterator;
CellIterator beginCell() const { return this->cells.begin(); }
CellIterator endCell() const { return this->cells.end(); }

其他提示

ipc+1不起作用的原因是,仅std::set支持双向迭代器,这支持operator++operator--;为了使用operator+,您需要使用随机访问迭代器。

一个问题我与您的设计看到的是,你的功能被命名为喜欢存取(getSuchAndSuch),但他们也修改对象的内部状态(ipc被修改)。这可能导致混淆。

一件事,你可以尝试将使用返回迭代器(一个beginend,例如)一些成员函数,并允许类的用户使用迭代器来访问内部设定,同时还封装集实施

您可以返回集合的迭代器类型,或者如果你想要更多的控制或封装,你可以实现一个包装集合的迭代器自己的迭代器类。

要防止暴露组:迭代(到不承诺用户超过需要的话)可以创建一个包装:

class Particle::iterator
{
public:
  iterator()
  {}
  iterator &operator++()
  {
    ++InternalIterator;
    return *this;
  }
  vtkIdType &operator*() const
  {
    return *InternalIterator;
  }
  ...//other functionality required by your iterator's contract in the same way
private:
  iterator(const std::set<vtkIdType> &internalIterator)
    :InternalIterator(internalIterator)
  {}
  std::set<vtkIdType>::iterator InternalIterator;
};

Particle::iterator Particle::GetBeginCell()
{
  return iterator(cells.begin());
}
Particle::iterator Particle::GetEndCell()
{
  return iterator(cells.end());
}

因此,你将摆脱内部迭代器(因为它是相当严格的,以便能够只有一个迭代器),并会得到使用来自STL算法对粒子的迭代器的能力。

也助推:: iterator_facade可能是有用的在这里...

真正的问题是你要在这里完成的。现在,你好像类(至少对我来说)做弊大于利 - 它与集更加困难,而不是容易的工作内容

我想看看粒子,并弄清楚它是否能提供一些有意义的事情超出了存储/访问一堆细胞的某种方式。如果真的只是一个简单的容器,那么你最好是用类似typedef std::set<cell> Particle;好了很多,所以最终用户可以使用算法和这种这套就像他们可以在任何其他。我只写一个类来封装,如果你真的可以封装有意义的事 - 即,如果你Particle类可以体现一些“知识”关于颗粒,这样其他的代码可以用粒子为这本身就是有意义的事情努力

现在,你Particle不过是一个容器 - 它看起来并不像一个特别好的容器,无论是。除非你真的可以添加一些东西,你可能会更好只使用什么是已经存在。

告诉你不这样做,除了三大干将的任何事情。通过使将使用粒子类的这些干将一部分,那么你就不需要在干将所有操作封装集:瞧,封装

如果你想留住你已经拥有了一般执行,而只是消除getFirstCell(),你可以在构造函数中初始化IPC。如上所述,明智地使用accessor和mutator之间const和明确的分化将澄清的接口。此外,如果你要实现你的类迭代器,那么我会建议addcell()返回一个迭代引用新的细胞,而是发生错误时抛出异常。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top