4

哪一个更好:

public:
  const vector<int> & GetPointsVector();
private:
  vector<int> PointsVector;

或者:

public:
  int GetCurrentPoint();
  void MoveToFirstPoint();
  void MoveToNextPoint();
  bool IsAtLastPoint();
  size_t GetNumberOfPoints();
private:
  vector<int> PointsVector;
4

5 回答 5

13

两者都不是。最好返回 begin() 和 end() 迭代器,或者更好地为迭代器返回 boost::range。

private:
        typedef std::vector<int>            PointsContainer;
public: 
        typedef boost::iterator_range<PointsContainer::const_iterator> PointsRange;
        PointsRange getPointsRange() const {
            return boost::make_iterator_range(pointsContainer_.begin(), pointsContainer_.end()); 
        }

优点是遍历逻辑隐藏在范围/迭代器内

使用时,一种替代方法是:

int p;
foreach(p, obj.getPointsRange()) {
   //...
}

除此以外

C::PointsRange r = obj.getPointsRange();
for(C::PointsRange::iterator i = r.begin(); i != r.end(); ++i) {
      int p = *i;
      //...
}
于 2009-03-25T09:01:27.543 回答
2

两者都不。将需要对类内部如此深入了解的函数变成成员函数。

于 2009-03-25T08:58:15.540 回答
2

在我看来,第一种选择(严格使用 const 关键字)更好,因为那时您可以使用标准接口来访问向量的成员(例如迭代器等)。只有当您没有其他选项来保护数据免受意外修改时,才需要第二个选项(即专用访问方法)。

于 2009-03-25T08:59:05.180 回答
2

没有正确的答案。答案会因上下文而异,目前我们掌握的很少。

这取决于您班级的客户。在大多数情况下,您不希望临时检查员更改对象的状态,因此在某种程度上最好返回对const对象的引用。但是,在这种情况下,我也会将函数const设为 ie

 /* a design const - this accessor does not change the state */
 const vector<int> & GetPointsVector() const;

这也很有效,因为您没有将重对象作为返回值传递(这是一个不同的问题,现在大多数编译器都执行 RVO)。

如果您的客户需要在算法中使用向量,是的,您最好提供迭代器。但是两对即

typedef vector<int>::iterator _MyItr;
_MyItr begin() const;
_MyItr begin();

_MyItr end() const;
_MyItr end();

这将与 STL 的设计方式保持一致。但是,在指定客户端可以期望的迭代器类型时要小心(例如:如果类规范说返回的迭代器是RandomIterators,它会对您的实现设置一定的期望值)。

于 2009-03-25T09:14:41.333 回答
0

我更喜欢封装内部数据表示并使用 forEachSomething 模板公共功能。或者,如果你有提升,你可以避免模板化 forEachSomething 并将实现放到 .cpp 文件中。

class Class
{
public:
    Class()
    {
        points_.push_back( 1 );
        points_.push_back( 5 );
        points_.push_back( 7 );
    }

    template <typename TFunction>
    void forEachPoint( TFunction function )
    {
        std::for_each( points_.begin(), points_.end(),
                       function );
    }

    void forEachPoint2( boost::function< void (int ) > function )
    {
        std::for_each( points_.begin(), points_.end(),
                       function );
    }
private:
    std::vector<int> points_;
};

void print( int a )
{
    std::cout << a << std::endl;
}

int main()
{
    Class object;
    object.forEachPoint( print );
}
于 2009-03-25T09:12:55.520 回答