面向?qū)ο?/h1>

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ù)表可以不同。

最后編輯于
?著作權(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)容