近發現一個挺有意思的東西,一問一答-http://wenda60.com/。
我這水平也就敢沖一下C++了,下面是一些記錄。
默認this指針
this指針是一個特殊的指針,當類的某個非靜態的成員函數在執行時,就會存在this指針。它指向類的一個對象,且這個對象的某個成員函數正在被調用。
this指針的名字始終是this,而且總是作為隱含參數傳遞給每一個被聲明的成員函數。
實際編程時函數的聲明不需要包含這個參數。
當程序中調用某個對象的成員函數時,編譯器會把該對象的地址加入到參數列表中。
靜態成員函數不存在this指針。
當調用某個對象的成員函數時,編譯器把對象的地址傳遞給this指針,然後再調用該函數。因此,成員函數你對任何成員的調用實際上都隱式地使用了this指針。
類的繼承規則
派生類共有三種C++類繼承方式:公有繼承(public),私有繼承(private),保護繼承(protected)
公有繼承(public)
基類的公有成員和保護成員可以作為其派生類的公有成員和保護成員
派生類的成員函數可以訪問基類中的公有成員和保護成員,無法訪問基類中的私有成員
派生類的對象可以訪問基類的公有成員
私有繼承(private)
基類的公有成員和保護成員都作為其派生類的私有成員
在私有繼承時,基類的成員只能由直接派生類訪問,而無法再往下繼承
保護C++類繼承(protected)
基類的所有公有成員和保護成員都成為派生類的保護成員
基類的公有成員和保護成員只能被它的直接派生類成員函數或友元訪問
構造函數和析構函數不能被繼承
因此構造派生類的對象時,需要對基類數據成員.新增數據成員和成員對象的數據成員進行初始化
派生類構造函數的參數表部分既需要包含子類某些數據成員的初始值,也要包含基類的數據成員的初始值
如果基類沒有默認的構造函數,那麼派生類必須具有給基類構造函數提供參數的構造函數
數組指針和指針數組
--------------指針----------------
int a=10;
int *p=&a;
-------------指針的指針-----------
int b=20;
int *p=&b;
int **p2p=&p;
-------------簡單數組-----------------
int c[10];//整數數組,含有10個整數元素
也就是說每一個元素都是整數
--------------指針數組--------------------
int *p[10];//指針數組,含有10個指針元素
也就是說每一個元素都是指針
--------------數組指針--------------------
int (*p)[10];//數組指針,這個指針可以用來指向
含有10個元素的整數數組
虛基類
虛基類的作用從上面的介紹可知:如果一個派生類有多個直接基類,而這些直接基類又有一個共同的基類,則在最終的派生類中會保留該間接共同基類數據成員的多份同名成員。
在引用這些同名的成員時,必須在派生類對象名後增加直接基類名,以避免產生二義性,使其惟一地標識一個成員,如
c1.A::display( )。
在一個類中保留間接共同基類的多份同名成員,這種現象是人們不希望出現的。C++提供虛基類(virtual base class )的方法,使得在繼承間接共同基類時只保留一份成員。
虛基類並不是在聲明基類時聲明的,而是在聲明派生類時,指定繼承方式時聲明的。因為一個基類可以在生成一個派生類時作為虛基類,而在生成另一個派生類時不作為虛基類。
聲明虛基類的一般形式為
class 派生類名: virtual 繼承方式 基類名
經過這樣的聲明後,當基類通過多條派生路徑被一個派生類繼承時,該派生類只繼承該基類一次。
需要注意: 為了保證虛基類在派生類中只繼承一次,應當在該基類的所有直接派生類中聲明為虛基類。否則仍然會出現對基類的多次繼承。
如果在派生類B和C中將類A聲明為虛基類,而在派生類D中沒有將類A聲明為虛基類,則在派生類E中,雖然從類B和C路徑派生的部分只保留一份基類成員,但從類D路徑派生的部分還保留一份基類成員。
使用多重繼承時要十分小心,經常會出現二義性問題。許多專業人員認為:不要提倡在程序中使用多重繼承,只有在比較簡單和不易出現二義性的情況或實在必要時才使用多重繼承,能用單一繼承解決的問題就不要使用多重繼承。也是由於這個原因,有些面向對象的程序設計語言(如Java,Smalltalk)並不支持多重繼承。
純虛函數
定義一個函數為虛函數,不代表函數為不被實現的函數。定義他為虛函數是為了允許用基類的指針來調用子類的這個函數。
定義一個函數為純虛函數,才代表函數沒有被實現。定義他是為了實現一個接口,起到一個規范的作用,規范繼承這個。類的程序員必須實現這個函數。
包含純虛函數的類稱為抽象類,不能初始話為對象。
break,continue和return
break
位置:只能用在switch語句和循環語句中。
作用:跳出switch語句或提前終止循環,轉去執行switch語句或循環語句之後的語句。
應用:多用於提前結束循環(包括省略形式的for循環),以避免死循環。
continue
位置:只能用在循環語句中。
作用:終止本次循環,即跳過其後尚未執行的循環體語句,並開始下一次循環。
區別:與break語句的區別是:continue語句結束本次循環,而break語句是結束整個循環。
return
位置:函數內部
return語句有兩種形式:
return;
return expression;
不帶返回值的return語句只能用於返回類型為void的函數,return語句是為了引起函數的強制結束,這種用法類似於循環結構中的break語句的作用。
返回類型為void的函數通常不能使用第二種形式的return語句,便是,它可以返回另一個返回類型同樣是void的函數的調用
任何返回類型不是void的函數都必須返回一個值,而且這個返回值的類型必須和函數的返回類型相同,或者能隱式轉化為函數的返回類型。
盡管C++不能確保結果的正確性,便能保證函數每一次return都返回適當類型的結果。
strlen和sizeof
char ss[100] = "0123456789";
sizeof(ss) 結果是100 ===》ss表示在內存中的大小 100×1
strlen(ss) 結果是10 ===》strlen是個函數內部實現是用一個循環計算到\0為止之前
char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
結果是 4 3 3 2
類模板和函數模板
模板是實現代碼復用的一種工具,它可以實現類型參數化,把類型定義為參數,實現代碼的真正復用。
模板分兩類:函數模板和類模板,用戶可使用他們來構造模板函數或模板類。模板經過實例化後就得到模板函數或模板類,模板函數或模板類再經過實例化後就得到對象。
函數模板可以用來創建一個通用的函數,以支持多種不同的形參,避免重載函數的函數體重復設計。它的最大特點是把函數使用的數據類型作為參數。
函數模板的數據類型參數標識符實際上是一個類型形參,在使用函數模板時,要將這個形參實例化為確定的數據類型。將類型形參實例化的參數稱為模板實參,用模板實參實例化的函數稱為模板函數。模板函數的生成就是將函數模板的類型形參實例化的過程。
類模板也稱為類屬類或類生成類,是為類定義的一種模式,它使類中的一些數據成員和成員函數的參數或返回值可以取任意的數據類型。類模板不是一個具體的類,它代表著一族類,是這一族類的統一模式。使用類模板就是要將它實例化為具體的類。
將類模板的模板參數實例化後生成的具體的類,就是模板類。
ofstream、ifstream和fstream
ofstream: 寫操作(輸出)的文件類 (由ostream引申而來)
ifstream: 讀操作(輸入)的文件類(由istream引申而來)
fstream: 可同時讀寫操作的文件類 (由iostream引申而來)
ofstream, ifstream 和 fstream所有這些類的成員函數open 都包含了一個默認打開文件的方式,這三個類的默認方式各不相同:
類 參數的默認方式
ofstream ios::out | ios::trunc
ifstream ios::in
fstream ios::in | ios::out
只有當函數被調用時沒有聲明方式參數的情況下,默認值才會被采用。如果函數被調用時聲明了任何參數,默認值將被完全改寫,而不會與調用參數組合。
常數據成員
類中的常數據成員的初始化,只能通過成員初始化列表的方式來進行。
用const修飾的定義對象稱為常對象;
用const修飾的聲明成員函數稱為常成員函數;
用const修飾的聲明數據成員稱為常數據成員。
變量或對象被 const修飾後其值不能被更新。因此被const修飾的變量或對象必須要進行初始化。
聲明方式:
const int cctwl;
int const cctwl;
int cctwl const; //這樣是錯誤的只能有以上兩種聲明形式。不能省略數據類型,可以添加 public private等訪問控制符
1.任何函數都不能對常數據成員賦值。
2. 構造函數對常數據成員進行初始化時也只能通過初始化列表進行。
3. 常數據成員在初始化時必須賦值或稱其必須初始化.
4. 如果類有多個默認構造函數必須都初始化常數據成員。