1.面向?qū)ο蠹夹g(shù)的基本概念
對(duì)象,類,繼承
2.C++中的空類默認(rèn)產(chǎn)生哪些成員函數(shù)
編譯器默認(rèn)產(chǎn)生默認(rèn)構(gòu)造函數(shù),析構(gòu)函數(shù),拷貝構(gòu)造函數(shù),賦值函數(shù)。
3.構(gòu)造函數(shù)
strct Test{
Test(int) {}
Test() {}
void fun(){}
};
int main(){
Test a(1);
a.fun();
Test b();//這里沒(méi)有參數(shù)傳遞的構(gòu)造函數(shù)直接用Test b;就可以了
//加了括號(hào)反而沒(méi)有真正實(shí)例化類對(duì)象
b.fun(); //編譯器會(huì)在這里檢查出錯(cuò)誤,b不是類對(duì)象
return 0;
}
4.成員變量
- 靜態(tài)成員變量時(shí)在一個(gè)類的所有實(shí)例間共享數(shù)據(jù)的,通常在定義時(shí)要初始化
- 靜態(tài)成員變量若為私有,可以通過(guò)共有靜態(tài)成員函數(shù)訪問(wèn)
- 初始化列表中的變量初始化順序是按照成員變量的聲明順序來(lái)執(zhí)行的
- 常量必須在構(gòu)造函數(shù)的初始化列表里初始化,或者將其設(shè)置成static
class A
{
const int Size = 0; //不對(duì)!
A(){const int Size = 9;//對(duì)!
static const int Size =9;//對(duì)!
}
5.構(gòu)造函數(shù)和析構(gòu)函數(shù)
- 析構(gòu)函數(shù)virtual原因:當(dāng)pBase指針撤銷時(shí),調(diào)用的是CBase的析構(gòu)函數(shù),而不是CChild的析構(gòu)函數(shù),這時(shí)內(nèi)存泄露。因?yàn)镃Child構(gòu)造時(shí)會(huì)先調(diào)用CBase的構(gòu)造函數(shù),然后CChild的構(gòu)造函數(shù),只有基類的析構(gòu)函數(shù)聲明為virtual時(shí),析構(gòu)時(shí)才會(huì)以同樣的順序依次調(diào)用基類的析構(gòu)函數(shù)。
CBase *pBase;
CChild c;
pBase = &c;
- 構(gòu)造函數(shù)不能是虛的
- 虛函數(shù)的開(kāi)銷:存在虛函數(shù)的對(duì)象需要維護(hù)一個(gè)向量表,如果僅是一個(gè)很小的類,且不想派生其他類,那么根本沒(méi)必要使用虛函數(shù)。
- 析構(gòu)函數(shù)的發(fā)生:函數(shù)返回時(shí)
6.String的函數(shù)
class String{
public:
String(const char *str = NULL);
String(const String &other);
~String(void);
String & operate = (const String &other);
private:
char *m_data;
}
//構(gòu)造函數(shù)
String::String(const char* str)
{
if( NULL == str)
{
m_data = new char[1];
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1];
strcpy(m_data,str);
}
}
//析構(gòu)函數(shù)
String::~String(void)
{
delete [] m_data;
}
//拷貝構(gòu)造函數(shù)
String::String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data,other.m_data);
}
//賦值函數(shù)
String& String::operater=(const String &other)
{
if(this = &other)
return *this;
delete [] m_data;
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data,other.m_data);
return *this;
}
7.多態(tài)的概念
- 一個(gè)接口,多種方法。封裝和繼承是為了代碼重用,而多態(tài)是為了接口重用。在調(diào)用函數(shù)時(shí),傳遞給函數(shù)的父對(duì)象的值可以是子對(duì)象,在運(yùn)行時(shí)根據(jù)傳遞的對(duì)象來(lái)確定具體的操作。
重載和覆蓋的區(qū)別:重載是靜態(tài)的,重載是編譯器根據(jù)函數(shù)不同參數(shù)表,對(duì)同名函數(shù)進(jìn)行修飾,在編譯期間已經(jīng)綁定了。而覆蓋是在子類重新定義了父類的虛函數(shù)后,父類根據(jù)賦給他的不同子類,動(dòng)態(tài)的調(diào)用屬于子類的該函數(shù),實(shí)現(xiàn)動(dòng)態(tài)綁定。
覆蓋需要一致的參數(shù)表和返回值,而重載參數(shù)表可以不同。