#pragma once
#include <string>
//定义在类内部的函数是隐式的inline函数
class Sales_data //class和struct的唯一区别就是默认的访问权限不同,class——private,struct——public
{
//友元声明,使非成员函数能访问非公有成员,注意:友元声明并非通常意义的函数声明,一般情况下,在类外单独进行函数声明
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::istream& read(std::istream&, Sales_data&);
friend std::ostream& print(std::ostream&, const Sales_data&);
public: //访问说明符
//构造函数
//只有当类没有声明任何构造函数是,编译器才会自动生成默认构造函数
Sales_data() = default;//合成默认构造函数
Sales_data(const std::string& s) :bookNo(s){ }//构造函数初始化列表,(变量初始化)可以用“( )”也可以用“{ }”
Sales_data(const std::string& s,unsigned n,double p):
bookNo(s),units_sold{n}, revenue{p* n} { }
Sales_data(std::istream &);
//类内部成员函数
//isbn方法的实际执行过程-->Sales::isbn(&Example),将实例的地址传递给isbn的隐式形参this
std::string isbn() const { return this->bookNo; }//const函数,类的数据成员为“只读”模式,相应的const成员只能访问const函数,参数列表可以看作(const Sales_data *const this)
Sales_data& combine(const Sales_data&);//两个&都是起到别名(引用)的作用,避免了临时变量的产生,注意:别名用作返回值不能返回局部变量
private: //访问说明符,封装了实现细节,只能被类的成员函数或者友元访问
double avg_price() const
{ return units_sold ? revenue / units_sold : 0; }
//成员数据
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
//在类外部定义构造函数
Sales_data::Sales_data(std::istream& is) {
read(is, *this);
}
//类外部定义成员函数,函数内部代码是位于类的作用域,隐式地使用了类内部的成员
Sales_data& Sales_data::combine(const Sales_data &rhs) {
units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this;
}
//类相关的非成员函数的声明
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);
std::istream& read(std::istream&, Sales_data&);
//类相关的非成员函数的定义
Sales_data add(const Sales_data &lhs, const Sales_data &rhs) {
Sales_data sum = lhs;
sum.combine(rhs);
return sum;//返回sum的副本
}
//IO类属于不能被拷贝的类型,只能通过引用来传递
std::ostream &print(std::ostream &os, const Sales_data &item) {//print函数不负责换行,输出函数尽量减少对格式的控制,确保用户代码的灵活性
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os;
}
std::istream &read(std::istream &is, Sales_data &item) {
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
经典永流传