考虑以下课程:
class SomeInfo
{
private:
std::vector<someObj *> _myVector;
public:
const std::vector<const someObj*>& getInfoVector() const
{
return _myVector;
}
};
当我尝试使用gcc 4.1.2编译时,它给出了以下错误:
error: invalid initialization of reference of type
‘const std::vector<const someObj*, std::allocator<const someObj*> >&’
from expression of type
‘const std::vector<someObj*, std::allocator<someObj*> >
如果我删除'someObj *'前面的'const',那么它会编译,但我不想返回带有非常量指针的向量,因为我不希望它们引用的对象是从我的SomeInfo类外部改变。在这种情况下你会做什么?
答案 0 :(得分:3)
在这种情况下我会做的是忘记返回vector
(或引用它)。调用者无法进行任何更改,因此无需查看任何特定容器。其他答案解释了为什么你不能将你的向量称为const someObj*
的向量。就此而言,如果您将来更改班级以使用deque
而不是vector
,则无法返回对该类的引用,就好像它也是向量一样。由于调用者只需要访问元素,让我们给他们:
const someObj *getInfoAt(size_t n) const {
return _myVector.at(n);
}
const_info_iterator getInfoBegin() const {
return _myVector.begin();
}
const_info_iterator getInfoEnd() const {
return _myVector.end();
}
size_t getInfoSize() const {
return _myVector.size();
}
// plus anything else they need.
const_info_iterator
是一个类的typedef,它写起来有些烦人。它必须包含std::vector<someObj *>::const_iterator
和const-ify operator*
的类型。 boost::transform_iterator
可能有用,或者从头开始编写并不是那么糟糕。但是,双向迭代器确实需要大多数操作符重载。
现在,如果调用者确实需要const someObj*
的向量,那么使用我的界面他们可以在任何特定时刻轻松获取快照:
std::vector<const someObj*> mycopy(myinfo.getInfoBegin(), myinfo.getInfoEnd());
他们所不能拥有的是vector
,它会不断反映其他地方某些其他类型的vector
所做的更改 - std::vector
只是不这样做。 / p>
答案 1 :(得分:0)
std::vector<T*>
和std::vector<const T*>
的类型不同。你怎么写这个:
std::vector<T*> obj(100);
std::vector<const T*> & ref = obj; //error
这是你在代码中所做的,这是无效的。您可以引用一种类型,以引用其他类型的对象。
所以试试这个:
std::vector<const someObj*> getInfoVector() const
{
return std::vector<const someObj*>(_myVector.begin(), _myVector.end());
}
现在它正在返回一个临时向量,其中包含原始向量中的指针。另请注意,返回类型不再是 引用。
答案 2 :(得分:0)
std::vector<const someObj*> getInfoVector() const
{
std::vector<const someObj*> obj;
std::copy( _myVector.begin(), _myVector.end(), std::back_inserter( obj ) );
return obj;
}
答案 3 :(得分:0)
在这种情况下你会做什么?
作为其他答案的替代方案,这是一个简单的方法,不需要复制或分配:
const someObj* SomeInfo::getSomeObjAt(const size_t& idx) const {
return this->_myVector.at(idx);
}
在许多情况下甚至更好,只是让SomeInfo 不暴露其内部。