Вызов неконстантной функции для константного объекта

Я читаю C++ Primer, 5-е издание, стр. 258. Вопрос в том, может ли константный объект вызывать свою неконстантную функцию-член, даже если эта функция-член не изменяет свои данные?

Sales_data.h

#include <iostream>
#include <string>

struct Sales_data {
    // data members
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;

    // memeber functions
    const std::string isbn() const { return bookNo; }
    Sales_data& combine(const Sales_data&);
    double avg_price() const { // *
        if (units_sold) {
            return revenue / units_sold;
        }
        return 0.0;
    }
};

std::ostream& print(std::ostream &os, const Sales_data& data) {
    os << data.isbn() << " " << data.units_sold << " " << data.avg_price();
    return os;
}

use_Sales_data.cpp

#include <iostream>
#include "Sales_data.h"
using  namespace std;

int main(){
    Sales_data data;
    data.bookNo = "CSAPP";
    data.units_sold = 2;
    data.revenue = 50;
    print(cout, data);
}

Когда я удаляю const для функции avg_price, код не компилируется. Но я думаю, что функция avg_price() не изменяет объект. Я предполагаю, что в списке параметров print я объявил объект Sales_data как const, а C++ не позволяет константному объекту вызывать свою неконстантную функцию-член. Так ли это?


person yyFred    schedule 11.07.2019    source источник


Ответы (1)


Да. Помните две вещи:

  1. Если функция непостоянна, она может быть вызвана только непостоянным объектом.
  2. Если функция константная, ее можно вызывать для любых объектов (я имею в виду любые константные или непостоянные объекты).

Причины:

  1. Если функция непостоянна, то ей разрешено изменять значения объекта, для которого она вызывается. Таким образом, компилятор не позволяет создать этот шанс и не позволяет вам вызывать непостоянную функцию для постоянного объекта, поскольку постоянный объект означает, что вы больше ничего не можете изменить. Таким образом, компилятор позволяет вам вызывать его только для непостоянного объекта, поскольку этот объект может быть изменен.
  2. Если функция сама по себе константа, то она обещает, что ничего не изменит в объекте, для которого она вызывается. Таким образом, компилятору все равно, вызываете ли вы константную функцию для постоянного или непостоянного объекта, поскольку сама функция не может изменить объект.
person hafiz031    schedule 11.07.2019