在const对象上调用非const函数

时间:2019-07-11 02:10:26

标签: c++ c++11 const member-functions const-correctness

我正在阅读C ++ Primer第5版第258页。问题是,即使该对象函数不修改其数据,const对象也可以调用其非const成员函数吗?

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的{​​{1}}时,代码将无法编译。但是我认为函数avg_price不会修改该对象。我的猜测是,在avg_price()的参数列表中,我将print对象声明为Sales_data,而C ++不允许const对象调用其nonconst成员函数。是这样吗?

1 个答案:

答案 0 :(得分:4)

是的。记住两件事-

  1. 如果函数是非常量的,则只能由 非恒定对象。
  2. 如果函数是常量,则可以在任何对象上调用它(我的意思是 任何常量或非常量对象。)

原因:

  1. 如果函数是非恒定的,则允许该函数执行以下操作: 更改在其上调用对象的值。所以 编译器不允许创建此机会并阻止您调用 常数对象上的非常数函数,例如常数对象 表示您无法再更改任何内容。所以只有编译器 允许您在非恒定对象上调用它,因为该对象可以是 已修改。
  2. 如果函数本身是常量,那么很有希望 不会更改被调用对象的任何内容。所以 编译器不在乎您是否在调用常量 在常数或非常数对象上的函数作为函数本身 无法更改对象。