What's the difference between a const member function and a non-const member function?

后端 未结 5 1840
清歌不尽
清歌不尽 2020-11-29 11:17

I am very confused about the const version and non-const version member function like below:

value_type& top() { return this.item }
const value_type&         


        
相关标签:
5条回答
  • 2020-11-29 11:43

    In short, they're used to add 'const correctness' to your program.

    value_type& top() { return this.item }
    

    This is used to provide mutable access to item. It is used so you can modify the element in the container.

    For example:

    c.top().set_property(5);  // OK - sets a property of 'item'
    cout << c.top().get_property();  // OK - gets a property of 'item'
    

    One common example for this pattern is returning mutable access to an element with vector::operator[int index].

    std::vector<int> v(5);
    v[0] = 1;  // Returns operator[] returns int&.
    

    On the other hand:

    const value_type& top() const { return this.item }
    

    This is used to provide const access to item. It's more restrictive than the previous version - but it has one advantage - you can call it on a const object.

    void Foo(const Container &c) {
       c.top();  // Since 'c' is const, you cannot modify it... so the const top is called.
       c.top().set_property(5);  // compile error can't modify const 'item'.
       c.top().get_property();   // OK, const access on 'item'. 
    }
    

    To follow the vector example:

    const std::vector<int> v(5, 2);
    v[0] = 5;  // compile error, can't mutate a const vector.
    std::cout << v[1];  // OK, const access to the vector.
    
    0 讨论(0)
  • 2020-11-29 11:43

    When member function is declared as const what's happening is that the implicit this pointer parameter passed to the function is typed to be a pointer to a const object. This allows the function to be called using a const object instance.

    value_type& top();    // this function cannot be called using a `const` object
    const value_type& top() const; // this function can be called on a `const` object
    
    0 讨论(0)
  • 2020-11-29 11:48

    value_type& top() { return this.item; } ensures that either the calling object's data members can be modified or the return value can be.

    value_type& top() const { return this.item; } ensures that the calling object's data members can't be modified, but the return value can be. So, for example, if I perform value_type item_of_x = x.top();, item_of_x can be modified but x cannot. Otherwise, a compiler error occurs (such as having the code this.item = someValue; inside of the function body).

    const value_type& top() { return this.item; } ensures that the calling object's data members are allowed to be modified, but the return value cannot be. It's the opposite of what is discussed above: if I perform const value_type item_of_x = x.top();, item_of_x can't be modified but x can. NOTE value_type item_of_x = x.top(); still allows for modification of item_of_x, as item_of_x is now non-const.

    const value_type& top() const { return this.item; } ensures that neither the calling object's data members can be modified nor the return value can be.

    0 讨论(0)
  • 2020-11-29 12:00

    The const-qualified member function will be called if the member function is called on an object that is const-qualified.

    The non-const-qualified member function will be called if the member function is called on an object that is not const-qualified.

    For example:

    MyStack s;
    s.top(); // calls non-const member function
    
    const MyStack t;
    t.top(); // calls const member function
    

    Note that the same rules apply when calling a member function on a reference to an object or through a pointer to an object: if the pointer or reference is to a const object, the const member function will be called; otherwise the non-const member function will be called.

    0 讨论(0)
  • 2020-11-29 12:03

    If you have

    class Foo
    {
        value_type& top() { return this.item }
        const value_type& top() const { return this.item }
    }
    

    If you have

    Foo foo;
    const Foo cfoo;
    

    The return types when you call top() are as follows:

    value_type& bar = foo.top();
    const value_type& cbar = cfoo.top();
    

    In other words - if you have a constant instance of your class, the const version of the function is chosen as the overload to call.

    The reason for this (in this particular case) is so that you can give out references to members (like item in this case) from a const instance of a class, and ensure that they too are const - thus unmodifiable and therefore preserving the const-ness of the instance they came from.

    0 讨论(0)
提交回复
热议问题