哪一个更好:
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;
答案 0 :(得分: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;
//...
}
答案 1 :(得分:2)
都不是。使需要对类内部的这种深入了解的函数成为一个成员函数。
答案 2 :(得分:2)
在我看来,第一个替代方法(严格地使用const关键字)更好,因为那时你可以使用标准接口来访问向量的成员(例如迭代器等)。仅当您没有其他选项来保护数据免遭意外修改时,才需要第二个选项(即专用访问方法)。
答案 3 :(得分:2)
没有正确答案。答案会因环境而异,目前我们的情况很少。
这取决于您班级的客户。在大多数情况下,您不希望临时检查器更改对象的状态,因此最好在某种程度上返回对const
对象的引用。但是,在这种情况下,我还要将函数设为const
,即
/* 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
,它会对您的实现设置一定的期望值。)
答案 4 :(得分: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 );
}