Постоянное значение функции для возвращаемого типа данных

Каково реальное значение const для 2-го объявления foo:B()?

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


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

Для 1-го объявления я точно знаю, что оно "защищает" переменную-член, т.е. m_var.

Но в чем весь смысл 2-го объявления о том, что оно просто возвращает константу int вызывающей стороне, вероятно, непостоянную переменную? Я имею в виду, имеет ли это смысл по какой-либо причине?

1 ответ

Случай 1: const после подписи функции говорит, что функция не изменит объект. Таким образом, вы можете использовать его на const объекты (или с указателем на const или const ссылка).

Случай 2: const перед именем функции действительно о типе возвращаемого значения. Вы совершенно правы: на практике это ничего не меняет для объекта, так как возвращение в этом фрагменте выполняется по значению, а это значение во временном интервале, которое нельзя изменить (например, ++ или -- не будет действительным в любом случае, потому что нет lvalue).

Случай 3: const в возвращаемом типе имеет больше смысла с возвратом указателя на const или ссылки на const. В этом случае это предотвратит изменение состояния объекта извне.

Вот краткое изложение:

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

онлайн демо

Случай 4: (спасибо HolyBlackCat за указание на это). То, что не имеет значения для скаляров в случае 2, может иметь смысл для классов. предполагать m_var будет класса bar:

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

Тогда возвращаемое значение const будет иметь значение:

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

онлайн демо

Другие вопросы по тегам