C++——內聯,友元

audience_fzn發表於2018-08-06

一、內聯(inline)

以inline修飾的函式叫行內函數,編譯時c++編譯器會在呼叫行內函數的地方將其展開,沒有函式壓棧的開銷,行內函數提升程式執行的效率。

  1. inline時一種以時間換空間的做法,省去呼叫函式的開銷,所以程式碼很長或內部有迴圈,遞迴的函式不適宜使用內聯
  2. inline對編譯器只是一個建議,編譯器會自動優化。如果定義為inline的函式體內有迴圈/遞迴等等,編譯器優化時會忽略掉內聯
  3. inline必須和函式的定義放在一起,才能稱為行內函數,僅將inline放在宣告前時不起作用的
  4. 定義在類內的成員函式預設為行內函數
class Date
{
public:
	void Func()//定義在類內的函式預設為行內函數
	{}
	void Display();
private:
	int _year;
	int _month;
	int _day;
};

inline void Date::Display()//成員函式類外定義為內聯
{
	cout << "year:" << _year << endl;
	cout << "month:" << _month << endl;
	cout << "day:" << _day << endl;
}

inline void Test()//全域性函式定義為內聯
{}

儘量使用const,enum,inline替換#define,為什麼?

巨集的優點:

  • 程式碼的複用性強
  • 可以提高程式的效能

巨集的缺點:

  • 不能除錯(預處理階段即進行了替換)
  • 沒有型別檢查
  • 可讀寫差,可維護性差

而#define定義的常量我們可以用const,enum代替,#define定義的巨集我們可以用inline進行替換,他們有著巨集的優點,卻不具備巨集的缺點。c++通過內聯機制,既具備巨集程式碼的效率,又增加了安全性,還可以資源操作類的資料成員,算是一個比較完美的解決方案

 

inline和巨集的區別:

  1. 行內函數和巨集一樣,將在被呼叫處進行程式碼展開,省去了引數壓棧,棧幀開闢回收的開銷,從而提高了程式的執行速度
  2. 行內函數相比巨集來說,在程式碼展開時,會做安全檢查或自動型別轉化,而巨集定義沒有引數型別檢查。
  3. 在類中宣告同時定義的成員函式預設為行內函數,使用行內函數可以訪問雷達成員變數,巨集定義則不能。
  4. 行內函數在執行時可以除錯,而巨集定義不能

二、友元(friend)

友元函式:

在C++中友元函式允許在類外訪問該類中的任何成員,就像成員函式用於,友元函式用關鍵字friend宣告

  • 友元函式不是類的成員函式
  • 友元函式可以通過物件訪問使用成員,私有和保護成員也一樣
class Date
{
	friend void Display(const Date &d);//定義為友元
private:
	int _year;
	int _month;
	int _day;
};

void Display(const Date &d)//類外訪問其私有成員
{
	cout << "year:" << d._year << endl;
	cout << "month:" << d._month << endl;
	cout << "day:" << d._day << endl;
}

void Test()
{
	Date d1;
	Display(d1);
}

輸入輸出運算子的友元函式

1.類中只要六個成員函式在不得已時會預設生成,其餘的如<<, >>要使用的話,必須過載

2.operator<<可以定義為成員函式嗎?

  • 可以將其放在類內定義,但是呼叫時的方式為d1.operator<<(cout)不符合我們常規的輸出方式,所以建議在類外定義

定義在類內:

如果按我們的輸出方式輸出的話會報錯:

所以建議定義在類外

class Date
{
public:
	friend ostream & operator<< (ostream& os, const Date& d);
	friend istream & operator>>(istream& is, const Date& d);
private:
	int _year;
	int _month;
	int _day;
};

ostream & operator << (ostream& os, const Date& d)
{
	os << "year:" << d._year << endl;
	os << "month:" << d._month << endl;
	os << "day:" << d._day << endl;
	return os;
}

istream & operator>> (istream& is, const Date& d)
{
	cout << "請輸入年月日" << endl;
	is >> d._year;
	is >> d._month;
	is >> d._day;
	return is;
}

3.operator<<函式的返回值,可以是void嗎? 

  • 不可以,因為我們要實現鏈式輸出,所以要用ostream&,istream&

友元類:

整個類可以是另一個類的友元,友元類的每個成員函式都是另一個類的友元函式,都可以訪問另一個類中的保護或者私有的資料成員

class Time
{
	friend class Date;//Date是Time的友元,它可以訪問Time的私有成員
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
public:
	void Display()
	{
		cout << _year << endl;
		cout << _month << endl;
		cout << _day << endl;
		cout << _t._hour << endl;
		cout << _t._minute << endl;
		cout << _t._second << endl;
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

友元一定程度上破壞了c++的封裝性,所以要用在適當的地方

相關文章