Maverick
Maverick

Reputation: 1187

Function's const meaning for the return data type

What is the real const meaning for the 2nd declaration foo:B() ?

int foo::A() const {
    return m_var; 
}


int const foo::B() {
    return m_var; 
}

For the 1st declaration I know for sure that it "protects" the member variable ie m_var.

But what the whole meaning of the 2nd declaration, which it just returns a constant int to the caller probably non-constant variable ? I mean does this make sense for any reason ?

Upvotes: 3

Views: 1768

Answers (1)

Christophe
Christophe

Reputation: 73366

Case 1: The const after the function signature says that the function will not change the object. So you can use it on const objects (or with pointer to const or a const reference).

Case 2: The const before the function name is indeed about the return type. You are completely right: in practice it doesn't change anything for the object, since the return is in this snippet done by value, and this value in a temp that cannot be changed (e.g. a ++ or a -- would not be valid anyway because there's no lvalue).

Case 3: The const in the return type would make more sense with the return of a pointer to const or a const reference. In this case it would prevent the object state to be changed from outside.

Here a summary:

class foo {
public:
    int A() const {   // const function
        return m_var; 
    }
    int const B() {   // non const function, but const return type
        return m_var; 
    }
    int const& C() const {   // non const function, but const reference return type
        return m_var; 
    }
private:
    int m_var; 
};

int main() {
    const foo x{}; 
    x.A();                // ok 
    //x.B();              // not ok -> function B() doesn't guarantee to leave x unchanged. 
    x.C();                // ok 
    const int& y = x.C(); // ok  (y will not alter m_var. 
    //int& z = x.C();       // not ok since z is not const 
    return 0;
}

online demo

Case 4: (thanks to HolyBlackCat for pointing it out). What make no difference for scalars in case 2 could perfectly make sense for classes. Suppose m_var would be of class bar :

class bar {
public: 
    void change_it() {}  
    void read_it() const {} 
}; 

Then the const return value would make a difference:

foo u{}; 
u.B();                // ok 
u.B().read_it();      // ok
u.B().change_it();    // not ok because of constness of B().  

online demo

Upvotes: 1

Related Questions