如何返回const std :: vector <object * const =“”>?</object>

时间:2010-12-15 11:06:29

标签: c++ stl const encapsulation

我有一个带有容器(包含指针)的类作为成员:

MyClass{
private:
   std::vector<MyObject*> _VecMyObjs;
public:
   const std::vector<MyObject* const> GetVecMyObj();
}

现在我尝试实现GetVecMyObj()。这就是我想出来的......

const vector<MyObject *const> ACI_CALL MyClass::GetVecMyObjs()
{
   const vector<MyObject *const> VecMyObjs;
   VecMyObjs.assign( _VecMyObjs.begin(), _VecMyObjs.end());
   return VecMyObjs;
}

但当然编译器警告我,我在const-Object上使用assign-function。有一个更好的方法吗?我的意思是,我不希望VecMyObjs在课堂之外改变VecMyObj。如果没有编译器警告,我怎样才能实现呢?

编辑: 好的。谢谢大家。它现在是这样的:

const vector<MyObject *const> ACI_CALL MyClass::GetVecMyObjs()
{
   const vector<MyObject *const> VecMyObjs;
   VecMyObjs.assign( _VecMyObjs.begin(), _VecMyObjs.end());
   return VecMyObjs;
}

但是,我无法绕过赋值函数,对吧?例如。如果我希望“一切”不变,那么施放“原始”是行不通的。

5 个答案:

答案 0 :(得分:3)

我不确定std::vector<MyObject * const>(常量指针的向量)是否真的是你想要的:我相信你的意思是std::vector<MyObject const *>(指向常量对象的向量)。

  1. constness( pointer constness)的“第一级”自然是通过在向量上返回一个常量引用来实现的。只能从const向量中获取const_iterator,因此您可以保证不会修改指针(但 pointees 可以)。

  2. constness( pointee constness)的“第二级”更难获得。要么像其他人已经指出的那样返回一个新的向量实例:

    return std::vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
    

    或者,如果适用,请尝试查看Boost Pointer Container库(最值得注意的是ptr_vector),其中包括正确的常量传播:

      

    传播constness,使其成为一个   无法通过a修改对象   常量性。

  3. 你必须明白,在向量上返回一个const引用可以保证它不能被修改(不能插入,删除或修改它的值)。因此,在大多数情况下,返回const std::vector<T> &是要走的路,因为如果不涉及任何复制。这里的问题非常特定于指针的容器,其中值的常量不提供指针的常量。

答案 1 :(得分:2)

如果您想要返回新的vector,请不要将其const。将const关键字放在*

之前
std::vector<MyObject const*> MyClass::GetVecMyObj()
{
    return std::vector<MyObject const*>(_VecMyObjs.begin(), _VecMyObjs.end());
}

我省略了转换为TRoadSgmt,因为您没有指定此类的继承。

答案 2 :(得分:1)

假设非const指针的向量存在于整个生命周期的某个地方,那么你将使用const-version,因此你不需要副本,如果有很多,那么你不需要要复制向量,最好返回一些自定义的包装器对象,只为用户提供const访问权。

向量的第一个元素的地址将是T **,你不能将它转换为const T **(正确),也不能将它转换为const T * const *(这是安全的但是语言不允许)。

如果允许你转换后者,那么创建一个只读视图是完美的。

答案 3 :(得分:0)

除了更改签名以从const中移除vector(因为它是向量的副本)之外,我假设您不希望外面的人修改内容,结果,制作一个const指针,即

vector<const MyObject *> ACI_CALL MyClass::GetVecMyObjs()
{
   return vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
}

现在返回的向量是一个副本,其中包含const指针(这意味着你不能通过这个指针修改指向的对象) - 这就是协议,没有什么可以阻止某人const_cast走了它(无论如何使用它是UB!)

如果您确实想要阻止修改,请在向量中返回副本(或克隆每个对象)。

答案 4 :(得分:0)

const vector<const MyObject *> MyClass::GetVecMyObjs() const
{
   return vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
}

这似乎是我的解决方案。我现在可以说,感谢我收到的所有不同帖子。 谢谢大家!祝你好一个...... (或者让我知道,如果我在某处仍然错了。)