GeekBand極客班C++面向?qū)ο蟾呒壘幊蹋ㄉ希┑谝恢芄P記

1.c++編程簡介

所需基礎(chǔ)知識

. 某種編程語言: 變量、類型、作用域、循環(huán)、流程控制

. 編譯、連結(jié)建立可執(zhí)行程序

學(xué)習(xí)目標(biāo)

. 培養(yǎng)正規(guī)、大氣的變成習(xí)慣:以良好的方式編寫c++class及class之間的關(guān)系

c++歷史

. B (1969) -> C (1972) -> C++ (1983)

. newC -> C with class -> C++

. c++98 、c++03 、c++11、 c++14

. {c++語言,c++標(biāo)準(zhǔn)庫}

2.頭文件與類的聲明

c vs. c++?

. c:{數(shù)據(jù)和結(jié)構(gòu)數(shù)據(jù),函數(shù)},數(shù)據(jù)是全局的可以被各個函數(shù)處理

. c++:{類數(shù)據(jù)和類結(jié)構(gòu)數(shù)據(jù),類函數(shù)},數(shù)據(jù)與處理該數(shù)據(jù)的函數(shù)打包在一起創(chuàng)建出對象

c++,關(guān)于數(shù)據(jù)和函數(shù)

. complex:{實部和虛部,加減乘除共軛正弦等等}

. string:{字符(ptr指向字符串),復(fù)制輸出附加插入}

基于對象vs.面向?qū)ο?/p>

. Object Based :面對單一class的設(shè)計

. Object Oriented :面對多重classes的設(shè)計,classes與classes之間關(guān)系

Classes的兩個經(jīng)典分類

. Class without pointer member(s) : 不帶有指針的函數(shù),例complex

. Class with pointer member(s) : 帶有指針的函數(shù),例string

c++ programs 代碼基本形式

. .h頭文件:類生命

. .h頭文件:標(biāo)準(zhǔn)庫

. .cpp主程序:{ #include <標(biāo)準(zhǔn)庫文件> ?or ?#include "聲明文件" } , 擴展名可能為其他

c++vs.c : Output

. 使用iostream.h


?#include <iostream.h>?

using namespace std;

int main()

{

? ? int i = 7;

? ? cout << "i = " << i << endl;

? ? return 0;

}


Header頭文件中的防衛(wèi)式聲明

. 用于防止重復(fù)include


#ifndef __COMPLEX__

#define __COMPLEX__

{}

#endif


Header頭文件的布局

. 0:forward declarations 前置聲明

. 1:class declarations 類聲明

. 2:class definition 類定義

class聲明declaration


class complex ? ? ? ? ? ? //class head

{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//class body

? ? public

? ? ? ? complex (double r = 0 , double i = 0)

? ? ? ? ? ? : re (r) , im (i)

? ? ? ? {}

? ? ? ? complex& ?operator += (const complex&);

? ? ? ? double real () const { return re;}

? ? ? ? double imag () const { return im;}

? ? private

? ? ? ? double re, im ;

? ? ? ? friend complex& __doapl (complex*, const complex&);

}


. 有些函數(shù)在body中直接定義,另一些在body之外定義

class template 模板簡介

. 模板用于:當(dāng)類需要用于不同類型數(shù)據(jù)時


template<typename T>

class complex

{}

{

? ? complex<int>c1

? ? complex<double>c2

}


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

inline內(nèi)聯(lián)函數(shù)

. 函數(shù)在body中定義可形成inline函數(shù)

. inline functions 就像宏一樣,但沒有宏的缺點,速度較快較好

. 但如果函數(shù)太復(fù)雜則不能inline

. 由編譯器決定函數(shù)是否inline,用戶只可以建議inline


inline double

imag(const complex& x)

{

return x.imag () ;

}


access level 訪問級別

. 用關(guān)鍵字區(qū)分:public、private

. private 所以數(shù)據(jù)都應(yīng)該放入private;只被自己使用不想被外界使用的函數(shù)也放這里;

. public 放被外界使用的函數(shù)

. protected保護,例子暫無

. 錯誤方式:



? ? complex c1(2,1);

? ? cout << c1.re ; ? ? ? ? ?// re變量只在private部分定義,不可以拿出來直接用

? ? cout << c1.im; ? ? ? ? ?//im同上


. 正確方式:


? ? complex c1(2,1);

? ? cout << c1.real(); ? ? ? ? //real函數(shù)定義于public部分,可以使用

? ? cout << c1.imag(); ? ? ?//imag同上


constructor. (ctor,構(gòu)造函數(shù))

. 函數(shù)名稱要與類名稱相同

. 參數(shù)與類中定義一致

. 參數(shù)默認(rèn)值default argument,創(chuàng)建時沒有指明參數(shù)值時使用默認(rèn)值

. 構(gòu)造函數(shù)沒有返回類型


? ? public:

? ? ? ? complex (double r = 0, double i = 0) ? ? ? ?//default argument

? ? ? ? ? : re (r) , im (i)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //initialization list? 初始值,初始列,給變量設(shè)置初始值,好的寫法,不將初始化寫入函數(shù)中,區(qū)分于函數(shù)中的賦值動作,充分應(yīng)用專門功能

? ? ? ? {} ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??


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


? ? complex c1(2,1);

? ? complex c2;

? ? complex* p = new complex(4); ? ? ? ? ?//動態(tài)創(chuàng)建,得到的是指針


. ctor構(gòu)造函數(shù)可以有很多個 - overloading 重載(即相同函數(shù)有很多個,如多種初值設(shè)定)

. 當(dāng)有多個構(gòu)造函數(shù)時,編譯器會在編譯后的實際名稱中加以區(qū)分

. 已經(jīng)存在有默認(rèn)值的構(gòu)造函數(shù),則不能再有無參數(shù)的相同構(gòu)造函數(shù)

4.參數(shù)傳遞與返回值

constructor(ctor)構(gòu)造函數(shù)放在private區(qū)

. 當(dāng)不允許外界創(chuàng)建類時,例如設(shè)計模式中的Singleton,只允許一個存在,外界通過函數(shù)取得

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

. 函數(shù)后加const,小括號后花括號前;對象前也可加const

. 不改變數(shù)據(jù)內(nèi)容的函數(shù),一定要加const

. 函數(shù)不加const的話,而當(dāng)用戶在對象前加const,編譯時候會出現(xiàn)矛盾


double real () const {return re;}


參數(shù)傳遞 pass by value vs. pass by reference (to const)

. by value:直接傳遞數(shù)值,整包value都傳過去,壓入函數(shù)棧。盡量不要用!

. by reference:傳遞引用地址,相當(dāng)于傳遞指針的速度

. 傳遞引用不希望數(shù)據(jù)被修改時,前加const


ostream&

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

{

return os << '(' << real (x) << ','

? ? ? ? ? ? ? ?<< imag (x) << ')' ? ?;

}


. 參數(shù)返回時也盡量要by reference

friend (友元)

. friend函數(shù)可以取得private數(shù)據(jù)


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

{

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

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

? ? return *ths;

}


. friend會打破封裝,選擇時需要考慮

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


class complex

{

? ? public:

? ? ? ? complex ()

? ? ? ? : 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);

}


class body外的各種定義definitions

. 什么情況可以pass by reference

. 什么情況可以return by reference:local變量要pass by value,其余都可以

5.操作符重載與臨時對象

. 在c++中操作符即是函數(shù),可以被重新定義

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

. 在成員函數(shù)中調(diào)用操作符的變量為this,但在參數(shù)列中不寫,調(diào)用時候可以寫


inline complex&

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

{

? ? return __doapl (this,r);

}

{

complex c1(2,1);

complex c2(5);

c2 += c1;

}


. doapl:賦值相加

return by reference 語法分析

. 傳送者無需知道接受者是否以reference形式接收,by value使用方法也一樣


inline complex&?

__doapl(complex* ths,const complex& r)

{

...

return *ths;

}

inline complex&?

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

{

return __doapl(this,r);

}


. 當(dāng)有連串動作發(fā)生時,如c3+=c2+=c1;返回值不可以是void

class body 之外的各種定義definition

operator overloading操作符重載2無this(非成員函數(shù))

. 為了應(yīng)付client的三種可能用法,需要對應(yīng)開發(fā)三個函數(shù)(復(fù)+復(fù),復(fù)+實,實+復(fù))

. 全局函數(shù),沒有this,調(diào)用參數(shù)要寫全,函數(shù)名前沒有class名

temp object 臨時對象 typename();

. 下面函數(shù)絕不可return by reference,因為他們返回值必須是個local object


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 complex(real (x) + y , imag (x) ?) ;

}

inline complex

operator + (double x , const complex& y)

{

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

}


. 創(chuàng)建臨時對象:typename();不需要命名。括號中可有參數(shù),生命到下一行就結(jié)束了

. 正負(fù)操作符,正操作符可試一下return by reference看看是否可行,負(fù)操作符必須return by value

. 相等、不等操作符,基本同前

. 共軛

. 對于output operator 等特殊操作符,不可以寫為成員函數(shù),只能將其重載為global函數(shù)

. 輸入流ostream&前不可加const .也有連串使用情況,所以要考慮返回值


inline complex

conj (const complex& x)

{

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

}

#include <iostream.h>

ostream&

operatro << (ostream& os, const complex& x)

{

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

}

{

? ? complex c1(2,1);

? ? cout << conj(c1);

? ? cout << c1 << conj(c1);

}


總結(jié)整理:

.注意點:防衛(wèi)式定義一定要有、初始行要用、函數(shù)一定要考慮加不加const、參數(shù)盡量pass by reference以及是否加const、考慮return by reference、數(shù)據(jù)幾乎無外放在private、函數(shù)大多放在public?

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

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