const成员函数

时间:2011-05-18 03:33:35

标签: c++

我有以下代码:

class Test{
private:
    int id;
public:
     Test(int v):id(v) {}
     int getId() { return id;};          // however,I change this method signature
                                            int getId() const { return id;};
                                            and all the errors gone
};

 struct compare{
   bool operator()(const Test& t1, const Test& t2){
    return t1.getId() < t2.getId();      // got error here
   }  
 };

 int main(int argc, char *argv[]){
   set<Test, compare> s;
   Test str[] = {Test(1), Test(2), Test(3)};
   for (int i = 0; i < 3; ++i){
     s.insert(str[i]);
   }
   for (set<Test>::iterator it = s.begin(); it != s.end(); ++it){
     cout << it->getId() << "\n";        // got error here
   }    
   return EXIT_SUCCESS;
 }

当我使用该代码调用方法getId()时出现此错误:

passing `const Test' as `this' argument of `int Test::getId()' discards qualifiers

我不知道为什么我需要在方法getId()中使用 const 来修复该错误?感谢

5 个答案:

答案 0 :(得分:10)

bool operator()(const Test& t1, const Test& t2)

您的操作员会引用const Test个对象。您只能通过引用const - 限定类型来调用const - 合格的成员函数。

set<Test>::iterator it = s.begin()

std::set的元素是不可变的:你无法改变它们。因此,std::set中的迭代器始终为const - 限定类型的对象。

答案 1 :(得分:3)

set::iterator只允许const访问元素,因为更改可能会影响集合元素的相对顺序 - 它需要保护的不变量(即如果更改集合中的元素,则为可能会破坏集合中元素的假定排序,并且将来的查找,插入等将无法按预期可靠地工作)。因此,只能通过const对元素访问调用iterator个成员函数。

这有点令人困惑,因为对于其他一些容器,const_iterator vs iterator的选择决定了授予的访问权限。

答案 2 :(得分:2)

const Test& t1

使t1保持不变,也就是说,不能通过此引用更改它。现在,您在该对象上调用的任何函数都可以更改其内部状态 - const不允许这样做!

这是怎么解决的?只需标记不会将内部状态更改为const的函数!这意味着,可以在const对象/引用/指针上调用它们 这就是为什么在const函数之后需要getId的原因,以确保您不会更改任何内部状态。

int getId() const { return id;};

修改:当然,这同样适用于std::set,但我不会进入其中,因为其他答案已经这样做了。

答案 3 :(得分:1)

您只能在const对象上调用const成员函数。

set<Test>::iterator it = s.begin(); 

返回一个const对象,所以你只调用带有这个对象的const类型的调用成员函数。

答案 4 :(得分:0)

operator()在其参数列表中有const Test&个对象,所以当你通过const对象调用时,你的函数需要用const限定符声明。

int getId() const { return id;};

同样改变,

for (std::set<Test, compare>::const_iterator it = s.begin(); it != s.end(); ++it){
       std::cout << it->getId() << "\n";        // got error here
   }