我有一个具有子控件指针的std :: vector的类。出于显而易见的原因,我不希望类的用户直接访问std :: vector。我想要的只是给调用者提供指针的方法。什么是一个很好的OO方式来做到这一点? (经常调用此函数)
由于
答案 0 :(得分:14)
提供一个向矢量返回const_iterator
的函数。添加一个以将迭代器返回到向量的末尾也很有用。
class MyClass {
public:
typedef vector<T>::const_iterator c_iter;
c_iter getBegin() const {return v.begin();}
c_iter getEnd() const {return v.end();}
// and perhaps if it's useful and not too invasive.
const T& getAt(int i) const {return v.at(i);}
//stuff
vector<T> v;
};
答案 1 :(得分:3)
迭代器是一种很好的,明显的方法。访问者模式是让客户端代码能够对向量中的每个元素进行操作的另一种方式:在某些方面,它甚至更清晰,对用户的暴露更少,并允许容器更多控制,例如:
BUT
begin()
,是否递增,以及find()
等其他操作:这是一个更清晰的功能因素。 / LI>
这看起来像是:
class Container
{
public:
template <typename Visitor>
void visit(Visitor& visitor)
{
for (Vector::const_iterator i = v_.begin(); i != v_.end(); ++i)
visitor(*i);
}
private:
typedef std::vector<X> Vector;
Vector v_;
};
// client code...
struct Visitor
{
void operator()(const X&) { ... }
// any data you want to update as you iterate...
};
Visitor v(...any construction arguments...);
container.visit(v);
答案 2 :(得分:1)
我通常会这样做:
class MyClass {
public:
const unsigned int GetNumberOfItems() { return v.size(); }
T* GetItemNumber(const unsigned int n)
{
// 3 options here, thrown your own exception type, or use the std one, or
// or just return NULL meaning nothing there or out of range.
try{
return v.at(n);
} catch (std::out_of_range &e){
}
return NULL;
}
vector<T> v;
};
然后你可以做类似的事情:
MyClass cl;
int count = cl.GetNumberOfItems();
for (int i = 0; i < cl.GetNumberOfItems(); i++){
T* item = cl.GetItemNumber(i);
}
不需要外部世界的迭代器。如果您必须将此类内容暴露给标准C API,那么它很容易公开。