(GeekBand)First class

一、頭文件與類的聲明

1.guard(防衛(wèi)式聲明)

在complex.h文件中寫出:

#ifndef?__COMPLEX__

#define?__COMPLEX__

? ? …

#endif

2.header的布局

0--forward declarations(前置聲明)

1--class declarations(類聲明)

2--class definition(類定義)

3.class declaration

class head

class body

二、構(gòu)造函數(shù)

1.class template

template

class classname

{

public:

? ? ......

private:

? ? T data1,data2;

};

2.inline 函數(shù)

(1)內(nèi)聯(lián)的目的:

1. C中使用define這種形式宏定義的原因是因?yàn)椋珻語言是一個(gè)效率很高的語言,這種宏定義在形式及使用上像一個(gè)函數(shù),但它使用預(yù)處理器實(shí)現(xiàn),沒有了參數(shù)壓棧,代碼生成等一系列的操作,因此,效率很高,這是它在C中被使用的一個(gè)主要原因。

2. 這種宏定義在形式上類似于一個(gè)函數(shù),但在使用它時(shí),僅僅只是做預(yù)處理器符號(hào)表中的簡(jiǎn)單替換,因此它不能進(jìn)行參數(shù)有效性的檢測(cè),也就不能享受C++編譯器嚴(yán)格類型檢查的好處,另外它的返回值也不能被強(qiáng)制轉(zhuǎn)換為可轉(zhuǎn)換的合適的類型,這樣,它的使用就存在著一系列的隱患和局限性。

3. 在C++中引入了類及類的訪問控制,這樣,如果一個(gè)操作或者說一個(gè)表達(dá)式涉及到類的保護(hù)成員或私有成員,你就不可能使用這種宏定義來實(shí)現(xiàn)(因?yàn)闊o法將this指針放在合適的位置)。

4. inline 推出的目的,也正是為了取代這種表達(dá)式形式的宏定義,它消除了宏定義的缺點(diǎn),同時(shí)又很好地繼承了宏定義的優(yōu)點(diǎn)。

(2)內(nèi)聯(lián)原理:

直接執(zhí)行替換而不進(jìn)行一般函數(shù)的參數(shù)壓棧,在預(yù)處理階段即可完成。

1. inline 定義的類的內(nèi)聯(lián)函數(shù),函數(shù)的代碼被放入符號(hào)表中,在使用時(shí)直接進(jìn)行替換,(像宏一樣展開),沒有了調(diào)用的開銷,效率也很高。

2. 很明顯,類的內(nèi)聯(lián)函數(shù)也是一個(gè)真正的函數(shù),編譯器在調(diào)用一個(gè)內(nèi)聯(lián)函數(shù)時(shí),會(huì)首先檢查它的參數(shù)的類型,保證調(diào)用正確。然后進(jìn)行一系列的相關(guān)檢查,就像對(duì)待任何一個(gè)真正的函數(shù)一樣。這樣就消除了它的隱患和局限性。

3. inline 可以作為某個(gè)類的成員函數(shù),當(dāng)然就可以在其中使用所在類的保護(hù)成員及私有成員。

(3)內(nèi)聯(lián)的用法:

函數(shù)若在class body內(nèi)定義完成,便自動(dòng)成為inline候選。在外部定義的成員函數(shù)需要顯式的添加上inline。外部全局函數(shù)也是直接在前面加上inline。

內(nèi)聯(lián)函數(shù)最重要的使用地方是用于類的存取函數(shù)

(4)內(nèi)聯(lián)成功的條件:

1.沒有分支(循環(huán)、開關(guān))沒有函數(shù)調(diào)用;

2.沒有取函數(shù)指針的操作;

3.函數(shù)形式簡(jiǎn)單。

3.訪問級(jí)別

4.構(gòu)造函數(shù)

目的:創(chuàng)建對(duì)象是完成初始化。

用法:

1.構(gòu)造函數(shù)的命名必須和類名完全相同;

2.沒有返回值,也不能用void來修飾;

3.構(gòu)造函數(shù)不能被直接調(diào)用,必須通過new運(yùn)算符在創(chuàng)建對(duì)象時(shí)才會(huì)自動(dòng)調(diào)用;

4.構(gòu)造函數(shù)有回滾的效果,構(gòu)造函數(shù)拋出異常時(shí),構(gòu)造的是一個(gè)不完整對(duì)象,會(huì)回滾,將此不完整對(duì)象的成員釋放;

5.如果一個(gè)類中沒有定義任何的構(gòu)造函數(shù),那么編譯器只有在以下三種情況,才會(huì)提供默認(rèn)構(gòu)造函數(shù):a.如果類有虛擬成員函數(shù)或者虛擬繼承父類(即有虛擬基類)時(shí);b.如果類的基類有構(gòu)造函數(shù)(可以是用戶定義的構(gòu)造函數(shù),或編譯器提供的默認(rèn)構(gòu)造函數(shù));c.在類中的所有非靜態(tài)的對(duì)象數(shù)據(jù)成員,它們對(duì)應(yīng)的類中有構(gòu)造函數(shù)(可以是用戶定義的構(gòu)造函數(shù),或編譯器提供的默認(rèn)構(gòu)造函數(shù))。

5.構(gòu)造函數(shù)可以有很多個(gè)(操作符重載-1,overloading)

事實(shí)上重載會(huì)以函數(shù)名加參數(shù)名組合一起命名。

三、參數(shù)傳遞與返回值

1.單例模式(singleton)

1.私有構(gòu)造函數(shù)不能通過new關(guān)鍵字來創(chuàng)建其對(duì)象,一個(gè)應(yīng)用是單例模式(singleton);

2.單例模式的要點(diǎn)有三個(gè);一是某個(gè)類只能有一個(gè)實(shí)例;二是它必須自行創(chuàng)建這個(gè)實(shí)例;三是它必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。

2.const member functions(常量成員函數(shù))

返回類型 成員函數(shù) const { ... };//function內(nèi)部不允許改變本類的數(shù)據(jù)

3.參數(shù)傳遞

pass by value ?or ?pass by reference (Is or not to const?))

一般,基本類型用pass by value;復(fù)雜類型用pass by reference。盡可能保證參數(shù)傳遞較少的值;

4.返回值傳遞

return by value?or?return?by reference(Is or not to const?))

1.盡可能保證返回值傳遞較少的值;

2.不可返回local變量的引用。牢記作用域!

5.友元函數(shù)

1.可以自由取得friend的private成員。

2.相同class的不同object互為友元。

class?complex

{

public:

? ? complex (double r = 0, double i = 0) : re(r), im(i){ }

? ? int func(const?complex & param)?{ return?param.re + param.im; }

private:

? ? double re, im;

};

{

? ? complex c1(2, 1);

? ? complex c2;

? ? c2.func(c1);

}

這里c2可以直接取得c1的私有變量。

6.classbody外的各種定義

注意不能傳遞局部變量的引用

doassignment?plus

inline?complex &?__doapl?(complex * ths, const comples & r)

{

? ? ths->re += r.re;

? ? ths->im += r.im;

? ? return *ths;

}

inline?complex &?complex::operator?+= (const complex&r)

{

? ? return __dopal (this, r);

}

四.操作符重載

1.operator overloading(操作符重載-1,成員函數(shù))有this

inline?complex &?__doapl?(complex * ths, const comples & r)

{

? ? ths->re += r.re;

? ? ths->im += r.im;

? ? return *ths;

}

inline?complex &?complex::operator?+= (const complex& r)

{

? ? return __dopal (this, r);

}

inline?complex &?complex::operator += (this, const complex& r)//this不能寫出來

{

? ? return __dopal (this, r);

}

{

? ? complexc1(2, 1);

? ? complexc2(5);

? ? c2 += c1;//操作到c2

}

2.returnby reference語言分析

傳遞著無需知道接收者是以reference形式接收

inlinecomplex &?__doapl?(complex * ths, const comples & r)

{

? ? ...

? ? return*ths;

}

inlinecomplex &?complex::operator?+= (const complex& r)

{

? ? return __dopal?(this, r);

}

這是相對(duì)于用指針的一大優(yōu)勢(shì)

3.operatoroverloading(操作符重載-2,非成員函數(shù))無this

inline?complex?operator?+ (const complex& x, const complex& y)

{

? ? return complex (real(x) + real(y),?imag(x) + imag(y));

}

inline?complex?operator?+ (const complex& x, double y)

{

? ? return comple(real(x) + y, imag(x));

}

inline?complex?operartor?+ (double x, const complex& y)

{

? ? return complex(x + real(y), imag(y));

}

4.臨時(shí)對(duì)象typename();

//這里一定不能return by reference

inline complex operator + (const complex& x, const complex& y)

{

? ? return complex (real(x) + real(y),?imag(x) + imag(y));//這個(gè)返回是一個(gè)local?object

}

{

? ? int(7);

? ? complex c1(2, 1);

? ? complex c2;

? ? complex();

? ? comple(4, 5);//這兩個(gè)臨時(shí)對(duì)象到下面就沒了

? ? cout << complex(2);

}

5.一元運(yùn)算符的重載

inline?complex?operator?+ (const comple& x)

{

? ? return x;

}

inline?complex?operator?- (const complex& x)

{

? ? return complex(-real(x), -imag(x));

}

{

? ? complex c1(2, 1);

? ? complex c2;

? ? cout << -c1;

? ? cout << +c1;

}

其它:

兩個(gè)復(fù)數(shù)的等于,不等于,共軛復(fù)數(shù),模運(yùn)算,極坐標(biāo)到笛卡爾坐標(biāo)的轉(zhuǎn)換

inline?complex?conj?(const complex&x)

{

? ? return complex (real(x), -imag(x));

}

ostream&?operator?<< (ostream& os, const complex& x)

{

? ? return os << '(' << real(x) << ',' <<?imag(x) << ')';

}

設(shè)計(jì)一個(gè)類小結(jié):

1.成員函數(shù)盡量放到public,數(shù)據(jù)盡量放到private

2.函數(shù)參數(shù)傳遞盡量考慮pass by reference;加不加const要考慮

3.返回值盡量以return by reference,除非需要返回臨時(shí)對(duì)象

4.成員函數(shù)如果不改變數(shù)據(jù)值的,函數(shù)body大括號(hào)前要加const

5.盡量使用initializationlist初始化構(gòu)造函數(shù)和成員函數(shù)的值

1.構(gòu)造一個(gè)類的步驟:

a.防衛(wèi)式聲明別忘記;

b.這個(gè)類有哪些數(shù)據(jù),什么類型的?寫進(jìn)private區(qū);

c.構(gòu)造函數(shù)怎么寫?參數(shù)是否要有默認(rèn)值?參數(shù)是否有必要returnby reference?沒有返回類型。寫進(jìn)public區(qū)。

d.是否要有取得私有數(shù)據(jù)值的函數(shù)的成員函數(shù),寫進(jìn)public區(qū)。返回類型和參數(shù)return by reference?不改變成員變量所有要在類成員函數(shù)加const?

e.是否需要重載一些操作符?寫成全局函數(shù)形式還是成員函數(shù)形式?(全局形式可以完成更加泛型一些的操作,如果確定該重載操作符只與該對(duì)象本身有關(guān),就攜程成員函數(shù))

f.是否需要友元以便直接訪問私有數(shù)據(jù)?

2.類名后面加小括號(hào)可以創(chuàng)建臨時(shí)對(duì)象,可以用于返回值。

3.當(dāng)該對(duì)象與其他類型使用此重載操作符的的時(shí)候,需要全局函數(shù)重載。

4.盡量要寫<<的重載。

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容