2009-01-06 54 views
-1
#include "iostream" 
#include "vector" 


class ABC { 

    private: 
     bool m_b; 
    public: 
     ABC() : m_b(false) {} 

     ABC& setBool(bool b) { 
      m_b = b; 
      return *this; 
     } 

     bool getBool() const { 
      return m_b; 
     } 
}; 

void foo(const std::vector<ABC> &vec) { 

     vec[0].setBool(true); 
} 

int main(int argc, char*argv[]) { 

    std::vector<ABC> vecI; 
    ABC i; 
    vecI.push_back(i); 
    foo(vecI); 
} 

当我编译它,我得到这个错误:传递const ABC作为ABC& ABC::setBool(bool)丢弃预选赛编译器错误改变非const对象

任何想法,为什么会发生这种事this论点,因为该对象itelf不是不变。

回答

6

foo通过reference-to-const获取vec,并且不能更改常量。因此,要么删除调用setBool的行,要么确实要设置bool,请将参数类型更改为std :: vector &。

或将更加严格执行......你看,这两个函数存在:

T& vector<T>::operator[](int); 
T const& vector<T>::operator[](int) const; 

当你调用一个const对象“VEC [I]”,只有第二个是有效的,所以它被选中。但是这个超载显然返回T const &,这是你不能改变的。

+0

要添加一些细节,矢量有两个operator [],一个非const的返回一个引用,一个const返回一个const引用。因为你的向量是通过const引用传递的,所以编译器选择const运算符[],所以setBool在const ABC(引用)上被调用。 – 2009-01-06 21:13:47

0

foo需要const vector &,这意味着该向量的内容不能被修改。这又意味着您不允许在vecsetBoo的任何元素上调用非const成员函数。

0

该对象可能是const。尽管向量包含ABCs而不是const ABCs,但向量本身是const的,所以当您调用operator []时,将使用该操作符的const版本。 vector上的operator []的const版本返回一个vector :: const_reference。所以,从我可以告诉你试图调用常量ABC的非常量方法。

0

作为另一种解决方法,您可以在向量中存储指向ABC对象的指针,它将正常工作 - 尽管需要额外的成本来管理清理。在这种情况下,你不会修改矢量的内容,因为矢量只能保持指针。