我有一个带有容器(包含指针)的类作为成员:
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;
}
但是,我无法绕过赋值函数,对吧?例如。如果我希望“一切”不变,那么施放“原始”是行不通的。
答案 0 :(得分:3)
我不确定std::vector<MyObject * const>
(常量指针的向量)是否真的是你想要的:我相信你的意思是std::vector<MyObject const *>
(指向常量对象的向量)。
constness( pointer constness)的“第一级”自然是通过在向量上返回一个常量引用来实现的。只能从const向量中获取const_iterator
,因此您可以保证不会修改指针(但 pointees 可以)。
constness( pointee constness)的“第二级”更难获得。要么像其他人已经指出的那样返回一个新的向量实例:
return std::vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
或者,如果适用,请尝试查看Boost Pointer Container库(最值得注意的是ptr_vector),其中包括正确的常量传播:
传播constness,使其成为一个 无法通过a修改对象 常量性。
你必须明白,在向量上返回一个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());
}
这似乎是我的解决方案。我现在可以说,感谢我收到的所有不同帖子。 谢谢大家!祝你好一个...... (或者让我知道,如果我在某处仍然错了。)