C++菜鸟学习笔记系列(20)
本期主题:定义抽象类型
我们曾经在C++菜鸟学习笔记系列(5)中介绍了一些关于自定义数据类型的知识,在上一篇博客中我们定义的Sale_data类比较简单,只是在struct关键字中定义了一些基本数据类型组成一个结构体,对于这个Sale_data类允许类的用户直接访问它的数据成员,并且要求由用户编写操作。与之相反的我们在这一篇博客中主要是介绍抽象数据类型。
我们再来了解一下类:
类的基本思想是数据抽象和封装。数据抽象是一种依赖于接口和实现分离的编程技术。
(1)类的接口包括用户所能执行的操作;
(2)类的实现规则包括类的数据成员、负责接口实现的函数体以及定义类所需要的各种私有函数。
封装实现了类的接口和实现的分离。封装后的类隐藏了它的实现细节,也就是说类的用户只能使用接口而无法访问实现部分。
类要想实现数据抽象和封装需要定义一个抽象数据类型,在抽象数据类型中,有类的设计者负责考虑类的实现过程,而类的使用者(用户)负责抽象地思考类型做了什么,而无需了解类型的工作细节。
程序员们通常把使用其程序的人称为用户。类似的类的设计者也是为其用户设计并实现一个类型的人,而类的使用者则是用户。
在本篇博客中我们来通过分别作为设计者和用户两个不同的角色来理解抽象类的定义。
我们先来思考一下我们定义的Sale_data类要具体实现什么功能,包含什么操作:
一个isbn成员函数,用于返回对象的ISBN编号。
一个combine成员函数,用于将一个Sale_data对象加到另一个对象上。
一个名为add的函数,执行两个Sale_data对象的加法。
一个read函数,将数据从istream读入到Sale_data对象中。
一个print函数,将Sale_data对象的值输出到ostream。
最近事情比较多,不想写了,直接上代码吧。
sale_data.h头文件
#include <iostream> #include <string> struct sale_data { std::string isbn() const { return bookno; } sale_data& combine(const sale_data&); double avg_price() const { if (units_sold != 0) { return revenue / units_sold; } else { return 0; } } std::string bookno; int units_sold; double revenue; }; //double sale_data::avg_price() sale_data add (const sale_data& sd1, const sale_data& sd2); std::ostream &print (std::ostream &out, const sale_data &sd); std::istream &read (std::istream &in, sale_data &sd);
main.cpp文件
/* author:wxc_1998 date:2018/11/16 */ #include <iostream> #include "sale_data.h" using namespace std; void main() { sale_data total; if (read(cin,total)) { sale_data trans; while (read(cin,trans)) { if (total.bookno == trans.bookno) { total.combine(trans); } else { print (cout, total); cout << endl; total = trans; } } print(cout, total); cout << endl; } else { cerr << "No data?" << endl; } cout << "please press any key to continue!" << endl; cin.clear(); cin.sync(); cin.get(); }
combine.cpp文件
#include <iostream> #include "sale_data.h" sale_data& sale_data::combine(const sale_data& sd) { units_sold += sd.units_sold; revenue += sd.revenue; return *this; }
add.cpp文件
#include <iostream> #include "sale_data.h" sale_data add (const sale_data& sd1, const sale_data& sd2) { sale_data sum = sd1; sum.combine(sd2); return sum; }
read.cpp文件
#include <iostream> #include "sale_data.h" using namespace std; istream &read(istream &in, sale_data &sd) { double price = 0; in >> sd.bookno >> sd.units_sold >> price; sd.revenue = sd.units_sold * price; return in; }
print.cpp文件
#include <iostream> #include "sale_data.h" using namespace std; ostream &print(ostream &out, const sale_data &sd) { out << sd.bookno << " " << sd.units_sold << " " << sd.revenue << " " << sd.avg_price(); ; return out; }