带对象的向量的const_cast

时间:2009-01-06 02:19:39

标签: c++

据我所知,删除对象常量的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中的原始对象是否会发生变化,我说是的,因为我传递引用,这是有效的。你能建议替代品吗?

4 个答案:

答案 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库,它看起来就像您想要的那样。