据我所知,删除对象常量的const_cast很糟糕,
我有以下用例,
//note I cannot remove constness in the foo function
foo(const std::vector<Object> & objectVec) {
...
int size = (int) objectVec.size();
std::vector<Object> tempObjectVec;
//Indexing here is to just show a part of the vector being
//modified
for (int i=0; i < (int) size-5; ++i) {
Object &a = const_cast<Object&> objectVec[i];
tempObjectVec.push_back(a);
}
foo1(tempObjectVec);
}
如果我在foo1中更改tempObjectVec对象,ObjectVec中的原始对象是否会发生变化,我说是的,因为我传递引用,这是有效的。你能建议替代品吗?
答案 0 :(得分:3)
嗯,这取决于对象。但是当将对象传递给push_back时, 被复制。您可以通过向复制构造函数添加一些调试代码来检查这一点。因此,如果Object表现良好并且将不同的副本分开,那么foo1可以改变它所喜欢的向量。
更有效的方法是让foo1接受一个开始和结束迭代器:
void foo1(std::vector<Object>::const_iterator start,
std::vector<Object>::const_iterator end);
...
foo1(objectVec.begin(), objectVec.end() - 5);
如果你不使用const_cast,那么类型系统将确保foo1不会改变任何元素,因为它们是const_iterators。
答案 1 :(得分:1)
你的tempObjectVec
不能成为引用的载体,所以我认为它应该被声明为:
std::vector<Object> tempObjectVec;
当您执行tempObjectVec.push_back(a)
时,将生成该对象的副本以将其推入tempObjectVec
向量。由于这是复制,你甚至不需要使用const_cast
删除常量,我不清楚为什么你需要这样做。
答案 2 :(得分:1)
我相信这是你要找的声明:
const_cast<std::vector<Object>&> (objectVec)
这将返回对非常量std::vector
的引用,这应该适合foo1(我假设)。
修改原始示例:
foo(const std::vector<Object> & objectVec) {
...
foo1(const_cast<std::vector<Object> &>(objectVec));
}
但是,我建议查看foo1
的实际要求,要求它使用非const向量,因为您似乎表示您感兴趣的所有内容都在修改Object
个实例。
答案 3 :(得分:1)
正如其他人已经说过的那样,你的vector的push_back接受了引用,但随后它复制了它引用的对象。因此,最后您最终会在objectVec[i]
内找到tempObjectVec
的副本。
向量无法存储引用,因为它们无法分配(对它的赋值不会影响引用本身,而是影响引用的对象),这是对象要保存在向量中的要求。引用也没有对象。它们没有自己的尺寸。因此,它们不能被推入数组或任何向量中。通常,您希望在这样的容器中存储指针或智能指针以引用其他对象。查看boost pointer container
库,它看起来就像您想要的那样。