【共读Primer】60.[7.1]定义抽象数据 类 Page227

本章的内容是类, 类是数据的抽象和封装。

定义一个抽象数据类型

我们在前面使用过Sales_item类型,但是并没有过多的讲述这个类型。

现在我们来讲Sales_data类型改造为支持Sales_item的一个操作集合。

我们需要完成的操作如下:

1. isbn,用来返回对象编号。

2. combine ,用来代替Sales_item的 += 操作符

3. add ,用来替代Sales_item的 + 操作符

4. read, 用来替代Sales_item的 >> 操作符

5. print , 用来替代Sales_item的 << 操作符

我们使用替代函数来对之前的读取进行了一次重写

Sales_data total;
if(read(cin, total))
{
    Sales_data trans;
    while(read(cin, trans))
    {
        if(total.isbn() == trans.isbn())
        {
            total.conbine(trans);
        }
        else
        {
            print(cout, total) << endl;
            total = trans;
        }
    }
    print(cout, total) << endl;
}
else
{
    cerr << "No data?!" << endl;
}

接下来我们来定义真正的Sales_data内容

struct Sales_data
{
    std::string isbn() const {return bookNo;} // 直接定义在类内部的函数是隐式inline的函数
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
    std::string booNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
// 以下是非成员函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream & print(std::ostream&, const Sales_data&);
std::istream & read(std::istream&, Sales_data&);

先来看一下定义部分的代码  return bookNo; 

bookNo是属于调用该函数的那个类对象的成员变量bookNo。

而在函数定义时,类内的所有成员函数有一个隐藏的参数this,这个参数代表对象本身的指针。

所以,如果将isbn这个函数写为完整形式则是

std::string isbn(Sales_data* this){return this->booNo;}

而紧跟在函数声明后const的作用是对这个this指针进行修饰,展开完整形式是

std::string isbn(const Sales_data * const this){return this->bookNo;}
//与成员函数std::string isbn()const {return bookNo;}等价

在函数声明的实际规则中正如我上面描述的这样,但是代码却不能这样来写,这样的写法只是帮助我们理解类内函数的这个事实

定义需要的函数

double Sales_data::avg_price() const 
{
    if(units_sold)
    {
        return revenue / units_sold;
    }
    else
    {
        return 0;
    }
}
// 这里直接返回的是调用对象本身
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

定义其他非成员函数

这些函数虽然服务于Sales_data类型,但是并不属于这个类。

一般需要将这些互有关系的函数放在同一个头文件中

istream & read(istream &is, Sales_data &item)
{
    double price = 0;
    is >> item.bookNo >> item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}

ostream & print(ostream &os, const Sales_data &item)
{
    os << item.isbn() << " " << item.units_sold << " "
    << item.revenue << " " << item.avg_price();
    return os;
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
    Sales_data sum = lhs;
    sum.combine(rhs);
    return sum;
}

 

posted @ 2018-09-12 09:57  chattyku  阅读(196)  评论(0)    收藏  举报