我有一个班级:
class X {
vector<shared_ptr<T>> v_;
public:
vector<shared_ptr<const T>> getTs() { return v_; }
};
vector
shared_ptr
类型为T
。出于某种原因,它需要公开一个方法来返回这个向量。但是,我不希望修改向量的内容,也不希望对象被指向。所以我需要返回vector
shared_ptr<const T>
。
我的问题是,有没有有效的方法来实现这一目标?如果我只是返回它,它可以工作,但它需要重建一个矢量,这是一种昂贵的。
感谢。
答案 0 :(得分:4)
你不能直接这样做 - 但你可以在容器上定义“views”,让你做一些非常相似的事情,如果你想确保你的pointees是const:
boost::any_range<
std::shared_ptr<const int>,
boost::random_access_traversal_tag,
std::shared_ptr<const int>,
std::ptrdiff_t
> foo(std::vector<std::shared_ptr<int>>& v)
{
return v;
}
一个简单的变换迭代器适配器/转换范围也可以做到这一点,我只是用它来说明这一点。
答案 1 :(得分:2)
为什么不将它作为一组iterator
s?
class X {
vector<shared_ptr<T>> v_;
class const_iterator : std::iterator< std::bidirectional_iterator_tag, T >
{
vector<shared_ptr<T>>::iterator it;
const_iterator( vector<shared_ptr<T>>::iterator& v ) :it (v) { }
const T& operator*() { return const_cast<const T>( **it ); }
//forward all methods
}
public:
const_iterator ts_begin() { return const_iterator(v_.begin()); }
const_iterator ts_end() { return const_iterator(v_.end()); }
};
或类似的东西?这使您可以完全控制类型及其访问方式。此外,您可以稍后更改类型,而无需更改API。
答案 2 :(得分:1)
您将按值返回,因此无论您返回原始数据的副本,向量还是shared_ptr<T const>
向量的副本,成本都是相同的:一个内存分配和N个原子增量(大约)。
如果要避免的是创建返回的向量(即按值返回),则不可能因为不同的模板实例化是不相关的类型,无论模板的参数有多相关。
答案 3 :(得分:0)
典型的解决方案是通过const引用返回:
class X {
vector<shared_ptr<T>> v_;
public:
const vector<shared_ptr<T>>& getTs() const { return v_; }
};
使用此返回类型vector<shared_ptr<T>>&
,其他对象无法修改内部向量。
但是然而这打破了封装。你的v_不再是X
的私密部分 - 它只是私有的写作方面。
真正的封装是:
class X {
vector<shared_ptr<T>> v_;
public:
class const_ts_iterator {
public:
//define all necessary stuff
private:
vector<shared_ptr<T>>::const_iterator it;
};
size_t getTsSize() const { return v_.size; }
const T* getTsAt(size_t i) const { return v_.at(i).get(); }
const_ts_iterator beginTs() const { return v_.cbegin(); }
const_ts_iterator endTs() const { return v_.cend(); }
};