C++Primer-第七章 類

第七章 類

類的基本思想是數據抽象封裝
數據抽象是一種依賴於接口實現分離的變成技術。

  • 類的接口包括用戶所能執行的操作
  • 類的實現則包括類的數據成員、負責接口實現的函數體以及定義類所需要的各種私有函數。

7.1 定義抽象數據類型

下面以 Sales_itme類和Sales_data類對抽象類型進行解釋

7.1.1 設計Sales_item

#include <iostream>
#include <string>
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章