在解决书店程序之前,我们还需要了解的唯一一个特性,就是如何定义一个数据结构(data structure)来表示销售数据。在C++中,我们通过定义一个类(class)来定义自己的数据结构。一个类定义了一个类型,以及与其关联的一组操作。类机制是C++最重要的特性之一。实际上,C++最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型(class type)。
在本节中,我们将介绍一个在编写书店程序中会用到的简单的类。当我们在后续章节中学习了更多关于类型、表达式、语句和函数的知识后,会真正实现这个类。
为了使用类,我们需要了解3件事情:
- 类名是什么?
- 它是在哪里定义的?
- 它支持什么操作?
对于书店程序来说,我们假定类名为Sales_item,头文件Sales_item.h中已经定义了这个类。
注:Sales_item.h的代码可以在下面查看(不理解没关系,等看完第10章就行了)
#ifndef SALESITEM_H #define SALESITEM_H #include#include class Sales_item { friend std::istream& operator>>(std::istream&, Sales_item&); friend std::ostream& operator<<(std::ostream&, const Sales_item&); friend bool operator<(const Sales_item&, const Sales_item&); friend bool operator==(const Sales_item&, const Sales_item&); public: Sales_item(): units_sold(0), revenue(0.0) { } Sales_item(const std::string &book): bookNo(book), units_sold(0), revenue(0.0) { } Sales_item(std::istream &is) { is >> *this; } public: Sales_item& operator+=(const Sales_item&); std::string isbn() const { return bookNo; } double avg_price() const; private: std::string bookNo; unsigned units_sold; double revenue; }; inline bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs) { return lhs.isbn() == rhs.isbn(); } Sales_item operator+(const Sales_item&, const Sales_item&); inline bool operator==(const Sales_item &lhs, const Sales_item &rhs) { return lhs.units_sold == rhs.units_sold && lhs.revenue == rhs.revenue && lhs.isbn() == rhs.isbn(); } inline bool operator!=(const Sales_item &lhs, const Sales_item &rhs) { return !(lhs == rhs); } Sales_item& Sales_item::operator+=(const Sales_item& rhs) { units_sold += rhs.units_sold; revenue += rhs.revenue; return *this; } Sales_item operator+(const Sales_item& lhs, const Sales_item& rhs) { Sales_item ret(lhs); ret += rhs; return ret; } std::istream& operator>>(std::istream& in, Sales_item& s) { double price; in>>s.bookNo>>s.units_sold>>price; if(in) s.revenue=s.units_sold * price; else s=Sales_item(); return in; } std::ostream& operator<<(std::ostream& out, const Sales_item& s) { out << s.isbn() << " " << s.units_sold << " " << s.revenue << " " << s.avg_price(); return out; } double Sales_item::avg_price() const { if (units_sold) return revenue/units_sold; else return 0; } #endif
如前所见,为了使用标准库设施,我们必须包含相关的头文件。类似的,我们也需要使用头文件来访问为自己的应用程序所定义的类。习惯上,头文件根据其中定义的类的名字来命名。我们通常使用.h作为头文件的后缀,但也有一些程序员习惯.H、.hpp或.hxx。标准库头文件通常不带后缀。编译器一般不关心头文件名的形式,但有的IDE对此有特定要求。
1.5.1 Sales_item 类Sales_item类的作用是表示一本书的总销售额、售出册数和平均售价。



