C++Primer-第七章 类

第七章 类

类的基本思想是数据抽象封装
数据抽象是一种依赖于接口实现分离的变成技术。

  • 类的接口包括用户所能执行的操作
  • 类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需要的各种私有函数。

7.1 定义抽象数据类型

下面以 Sales_itme类和Sales_data类对抽象类型进行解释

7.1.1 设计Sales_item

#include 
#include 
using namespace std;

struct Sales_data
{
	string isbn;
	unsigned unit_solid = 0;
	double revenue = 0.0;
	Sales_data& read(istream& is) {
		Sales_data sale_data;
		cout << "please input the isbn:" << endl;
		string s_isbn;
		char *c_isbn=new char[sizeof(s_isbn)];
		is.getline(c_isbn,sizeof(s_isbn));
		s_isbn=c_isbn;
		sale_data.isbn = s_isbn;
		cout << "please input the unit_sold:" << endl;
		char *c_unit_solid = new char[sizeof(c_unit_solid)];
		is.getline(c_unit_solid, sizeof(s_isbn));
		unsigned unit_solid = atoi(c_unit_solid);
		sale_data.unit_solid = unit_solid;
		cout << "please input the revenue:" << endl;
		char *c_revenue = new char[sizeof(c_unit_solid)];
		is.getline(c_unit_solid, sizeof(s_isbn));
		double revenue = atof(c_unit_solid);
		sale_data.revenue = revenue;
		return sale_data;
	}
	void print(ostream os) {

	}
};

简单写了个例子,感觉书本上面的例子有点复杂了
有类的抽象定义可以确定 Sales_data不是一个抽象数据类型,它允许类的用户直接访问他的数据成员,并且要求用户来编写操作。

7.1.2 定义改进的Sales_data类

把定义写在头文件中

struct Sales_data
{
	//新成员:关于Sales_data对象的操作
	string isbn() const {return bookNo;}
	Sales_data& combine(const Sales_data&);
	double avg_price() const;
}
//Sales_data的非成员接口函数
Sales_data add(const Sales_data&,const Sales_data&);
  • 定义成员函数
    成员函数体可以定义在类内也可以定义在类外。
  • 引入this
    在isbn()函数中只有一条return 语句,其实默认使用的this指针,可以理解为
    isbn(Sales_data& this)。
  • 引入const成员函数
    string isbn() const {return bookNo;} 在isbn()之后紧跟了一个const关键字,这里const的作用是修改隐式this指针的类型。
    在成员函数中,this的类型是Sales_data *this。尽管this是隐式的,但他仍然需要遵循初始化规则,意味着我们不能把this绑定到一个常量对象上。
    加上const之后,表示this是一个指向常量的指针。想这样使用const的成员函数被称作常量成员函数
    可以理解为:
    string Sales_data::isbn(const Sales_data *const this){return this->isbn};

常量对象,以及常量对象的引用或指针都只能调用常量成员函数。

7.1.3 定义类相关的非成员函数

  • 定义read和print函数
isstream &read(istream &is,Sales_data &item)
{
	double price=0;
}

7.1.4 构造函数

每个类都分别定义了他的对象初始化的方式,类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数

struct Sales_data
{
	Sales_data()=default			//默认构造函数
	Sales_data(const string& isbn):bookNo(isbn){} //用isbn初始化bookNo
}

7.2 访问控制和封装

  • 访问说明符
    • 定义在public说明符之后的成员在整个程序内可被访问,public成员定义类的接口。
    • 定义在private说明符之后的成员可以被类的成员函数访问,但是不能被使用该类的代码访问,private部分封装了类的实现细节。
class Sales_data{
public:			//添加了访问说明符
	Sales_data()=default;
	Sales_data(const string &isbn, unsigned units_sold, double revenue):bookNo(isbn),units_sold(units_sold),revenue(revenue*units_sold){}
	Sales_data(const string &isbn):bookNo(isbn){}
	string isbn() const {return bookNo;}
	Sales_data &combine(const Sales_data&);
private:		//添加了访问说明符
	double avg_price() const {return units_sold?revenue/units_sold:0;}
	string bookNo;
	unsigned units_sold=0;
	double revenue=0.0;
}
  • 使用class或struct关键字
    struct和class的默认访问权限不太一样,类可以在它的第一个访问说明符之前定义成员,对这种成员的访问权限依赖于类定义的方式。
    • 如果我们使用struct关键字,则定义在第一个访问说明符之前的成员是public
    • 如果我们使用class关键字,则这些成员是private的

使用class和struct定义类唯一的区别就是默认的访问权限

7.2.1 友元

类可以允许其他类或者函数访问他的非公有成员,方法是令其他类或者函数称为它的友元

class Sales_data{
//为Sales_data的非成员函数所有的友元声明
friend Sales_data add(const Sales_data&,const Sales_data&);
friend istream &read(std::istream&,Sales_data&);
friend ostream &print(std::ostream&,const Sales_data&);
//其他成员及访问说明符与之前一致
publicSales_data()=default;
	Sales_data(const std::string &isbn,unsigned unit_sold,double revenue):bookNo(isbn),unit_sold(unit_sold),revenue(revenue*unit_sold){}
private:
	std::string bookNo;
	unsigned unit_sold=0;
	double revenue=0.0;
};

类的用法和struct用法一样,可以参考struct

你可能感兴趣的:(c++学习)