c++單例模式、常量成員函式、引數傳遞、友元

Aerobatics發表於2020-11-17

單例模式(Singleton)

建構函式ctors放在private區

class A {
	public:
		static A& getInstance();
		setup() {...}
	private: //外界不能構造A(),外界只能用一份(單例)通過static訪問
	  	A()//建構函式
	  	A(const A& rhs);//建構函式
	  	...
};

A& A::getInstance()
{
	static A a;//這裡準備了一份(單例)A
	return a;
}

應用

A::getInstance().setup(); //class A中的getInstance()函式,取得那一份

常量成員函式

class complex
{
	public:
		...
		//常量成員函式
		//在函式後加const    ( ) const { }
		//這兩個函式是取得複數的實部和虛部
		//這兩個函式不會改變物件裡面的資料,只是從private的double re,im中取出來,並不改變其值
		double real () const { return re; }
		double imag () const { return im; }
	private:
		double re, im;
		friend complex& _doapl
};

應用

錯誤示範

{	//上述class complex中的函式double real() const {return re;} 含有const
	complex c1(2,1);
	cout << c1.real();
	cout << c1.imag();
}

正確示範

{	//const代表物件c1的內容不改變
	const complex c1(2,1);
	cout << c1.real();
	cout << c1.imag();
}

對類中的函式分為:

1.會改變資料(private下的資料)內容
2.不會改變資料(private下的資料)內容的,馬上加上const, const修飾的函式就是不改變資料內容(private下的資料)

引數傳遞

1.Pass by value,將資料整包傳遞入棧中
2.Pass by reference to const

class complex
{
	public:
		//pass by value
		//double如果是4個位元組就傳4個位元組
		complex (double r = 0, double i = 0)
			: re(r), im(i)
		{ }
		//pass by reference to const
		complex& operator += (const complex&);
		...
	private:
		double re, im;
		friend complex& _doapl (complex)
};

應用

{	//2,1被傳入complex (double r=0,double i=0):re(r),im(i){}
	complex c1(2,1);
	complex c2;
	//將c1傳到complex& operator += (const complex&);
	c2 += c1;
	cout << c2;
}

3.Pass by reference

ostream&
	//pass by reference
	//引用在底部就是一個指標,傳引用的效率相當於傳指標那麼快
	operator << (ostream& os, const complex& x)
	{
		return os << '(' << real (x) << ','
				  << imag (x) << ')';
	}

返回值傳遞

1.return by value

//第一個double是返回值型別
double real () const { return re; }
double imag () const { return im; }

2.return by reference

//第一個complex& 返回引用
complex& operator += (const complex&);

3.return by reference to const

// com
friend complex& _doapl (complex*, cosnt complex&);

注意事項:
1.資料一定放在private內
2.引數儘可能用引用(reference)來傳遞,要不要加const看具體狀況
3.返回值也儘量用引用(reference)來傳遞
4.在類的本體(body)內的函式,應該加const的就要加。如果不加,可能使用者去用的時候會報錯(編譯器會報錯)

friend(友元)

class complex
{
public:
	...
//不允許外部取得re,im 即封裝
//外部想要取得re,im可以通過double real()...函式來取得
private:
	double re, im;
	friend comple& _doapl (complex*, cosnt complex&);
};

應用

//上述friend 在class body內,所以為行內函數inline
inline complex&
_doapl (complex* ths, const complex& r)
{	//自由取得friend的private成員
	//傳入的引數ths要取出複數的實部re虛部im
	//friend開啟了封裝的大門
	//friend直接取資料,比通過函式取資料更快
	ths ->re += r.re;
	ths ->im += r.im;
	return *ths;
}

相同的class的各個objects互為friends(友元)

class complex
{
	public:
		complex (double r = 0, double i = 0)
			: re(r),im(i)
		{ }
		//func接收一個複數,該函式中直接獲得實部和虛部,而下面double re,im中訪問型別為private
		int func (const complex& param)
		{ return param.re + param.im;}
	private:
		double re, im;
};

應用

{
	//準備兩個複數
	complex c1(2,1);
	complex c2;
	//用第一個複數處理第二個複數,處理是直接取得複數的實部和虛部
	c2.func(c1);
}

class body外的各種定義

什麼情況下可以pass by reference
什麼情況下可以return by reference

inline complex&
_doapl (complex* ths, const complex& r)
//ths和r引數相加後給ths,返回的是相加後得到的新ths,函式消失後隨之消失,像local的變數或像local的物件,這時候不能return by reference
{	//c3=c1+c2加完的的結果放在c3
	//c1 += c2 等價於c1=c1+c2,c1是第一引數,c2是第二引數
	//第一引數將會被改動
	//第二引數不會被改動
	ths ->re += r.re;
	ths ->im += r.im;
	//以上建立的複數,當函式消失後,複數隨後死亡,所以引用便成為空,不能return by reference
	return *ths;
}
inline complex&
complex::operator += (const complex& r)
{
 	return _doapl (this, r);
}

相關文章