开发者

const member function

I have following piece of code:

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;
 }

I got this error when I called the method getId() with that code:

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

I don't know why I need 开发者_运维技巧const in the method getId() to fix that error ? Thanks


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

Your operator takes references to const Test objects. You can only call const-qualified member functions via a reference to a const-qualified type.

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

The elements of a std::set are immutable: you cannot change them. Because of this, iterators into a std::set are always to a const-qualified type of object.


The set::iterator only gives const access to the elements, as changes might affect the relative order of set elements - an invariant it needs to protect (i.e. if you change an element in the set, you could corrupt the assumed ordering of the elements in the set, and future lookups, insertions etc. wouldn't reliably work as expected). Therefore, only const member functions can be invoked on the element access via the iterator.

This is a bit confusing, as for some other containers the choice of const_iterator vs iterator dictates the access granted.


const Test& t1

Makes t1 constant, that is, it can not be changed through this reference. Now, any function you call on that object could possible change its internal state - which is not allowed with the const!

How is that solved? Just mark functions that don't change the internal state as const too! That means, they can be called on const objects / references / pointers.
That's why you need the const after your getId function, to ensure that you won't change any internal state.

int getId() const { return id;};

Edit: Of course, the same applies to std::set, but I won't go into that as other answers already did so.


You can call only const member functions on a const object.

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

returns a const object, So you call only call member functions which are const type with this object.


The operator() has const Test& objects in its parameter list so when you call through a const object your function needs to be declared with const qualifier.

int getId() const { return id;};

Also change,

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜