1. 程式人生 > >C++ 類的進階學習篇--建構函式、友元

C++ 類的進階學習篇--建構函式、友元

建構函式

每個類都分別定義了它的物件被初始化的方式,類通過一個或幾個特殊的成員函式來控制其物件的初始化過程,這些函式便是建構函式。它的任務就是初始化類物件的資料成員,無論何時只要類的物件被建立,就會執行建構函式。

預設初始化建構函式

在我們沒有定義建構函式時,類會通過一個特殊的建構函式來控制預設初始化過程,這個過程叫做預設建構函式,它無需任何實參。又被稱為合成的預設初始化建構函式

它會按照如下規則初始化類的資料成員

1.如果存在類內初始值,用它來初始化成員

2.否則,預設初始化該成員

注意:只有當類內沒有任何建構函式時,編譯器才會自動生成預設建構函式

定義建構函式

在類內定義建構函式

新增這樣幾個建構函式

Sales_data() = default;  //預設建構函式,如果我們需要預設的行為,那麼可以通過在引數列表後寫上 = default

Sales_data(const std::string &s) : bookNo(s) = {}

Sales_data(const std::string &s, unsigned n, double p) : bookNo(s), units_sold(n),  revenve(p*n) {}

//建構函式的初始值列表,上述 :後面跟的是初始值列表,{}內是函式體

Sales_data(std::istream &)

//這個是在類外定義建構函式

訪問控制與封裝

public:定義在public說明符之後的成員在整個程式內可被訪問,public定義類的介面。

private:定義在private說明符之後的成員可以被類的成員函式訪問,但是不能被使用該類的程式碼訪問,private隱藏了類的實現細節

/*
1.使用class定義
2.加上建構函式*/
class Sales_data {
public:
	Sales_data() = default;
	Sales_data(const std::string &s, unsigned n, double p) :
		bookNo(s), units_sold(n), revenue(p*n) {};
	Sales_data(const std::string &s) : bookNo(s) {};
	Sales_data(std::istream &);
	std::string isbn() const { return bookNo; }//返回ISBN編號
	Sales_data& combine(const Sales_data&);     //將一個Sales_date物件加到另一個物件上去
private:
	double avg_price() const
	{return units_sold ? revenue / units_sold : 0;}
	std::string bookNo;     //ISBN編號
	unsigned units_sold = 0;//銷售數量
	double revenue = 0.0;   //銷售總額

};

這次我們使用的是class定義類

那麼什麼時候使用class,什麼時候使用struct嘞

我這樣告訴你。

struct和class唯一不用的是他們的預設許可權。

所以為了統一程式設計風格,當我們希望所有類的成員都是public時,使用struct

                                       當我們希望成員有private時,使用class

友元

類允許其他類或戰術訪問它的非公有成員,方法時令其他類或者函式稱為它的友元。

那麼我新增下友元,上面的clss定義變為

class Sales_data {
	friend Sales_data add(const Sales_data&, const Sales_data&); //執行兩個Sales_date物件的加法
	friend std::ostream &print(std::ostream&, const Sales_data&);//將Sales_date物件輸出到ostream上
	friend std::istream &read(std::ostream&, Sales_data&); //從ostream上讀入到Sales_date物件

public:
	Sales_data() = default;
	Sales_data(const std::string &s, unsigned n, double p) :
		bookNo(s), units_sold(n), revenue(p*n) {};
	Sales_data(const std::string &s) : bookNo(s) {};
	Sales_data(std::istream &);
	std::string isbn() const { return bookNo; }//返回ISBN編號
	Sales_data& combine(const Sales_data&);     //將一個Sales_date物件加到另一個物件上去

private:
	double avg_price() const
	{return units_sold ? revenue / units_sold : 0;}
	std::string bookNo;     //ISBN編號
	unsigned units_sold = 0;//銷售數量
	double revenue = 0.0;   //銷售總額

};

Sales_data add(const Sales_data&, const Sales_data&); //執行兩個Sales_date物件的加法
std::ostream &print(std::ostream&, const Sales_data&);//將Sales_date物件輸出到ostream上
std::istream &read(std::ostream&, Sales_data&); //從ostream上讀入到Sales_date物件

當然友元的宣告僅僅只動了訪問的許可權,而一個通常意義上的函式宣告。如果我們希望類的使用者能夠掉以哦那個某個友元函式,那我們就必須在友元宣告之外再專門對函式進行一次宣告。

關於友元,這個哥講的ok