欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解c++中virtual關鍵字

 更新時間:2014年02月27日 09:43:38   投稿:jingxian  
本篇文章主要是對c++中virtual關鍵字進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助

1.virtual關鍵字主要是什么作用?
c++中的函數(shù)調(diào)用默認不適用動態(tài)綁定。要觸發(fā)動態(tài)綁定,必須滿足兩個條件:第一,指定為虛函數(shù);第二,通過基類類型的引用或指針調(diào)用。
由此可見,virtual主要主要是實現(xiàn)動態(tài)綁定。

2.那些情況下可以使用virtual關鍵字?
virtual可用來定義類函數(shù)和應用到虛繼承。

友元函數(shù) 構(gòu)造函數(shù) static靜態(tài)函數(shù) 不能用virtual關鍵字修飾;
普通成員函數(shù) 和析構(gòu)函數(shù) 可以用virtual關鍵字修飾;

3.virtual函數(shù)的效果

復制代碼 代碼如下:

class GrandFather
{
public:
 GrandFather() {}
 virtual void fun()
 {
  cout << "GrandFather call function!" << endl;
 }
};

class Father : public GrandFather
{
public:
  Father() {}
  void fun()
  {
   cout << "Father call function!" << endl;
  }
};


class Son : public Father
{
public:
 Son() {}
 void fun()
 {
  cout << "Son call function!" << endl;
 }
};

void print(GrandFather* father)
{
 father->fun();
}

int _tmain(int argc, _TCHAR* argv[])
{
 Father * pfather = new Son;
        pfather->fun();
        GrandFather * pgfather = new Father;
        print(pgfather);
 return 0;
}


輸出為 Son call function
       Father call function

4.virtual的繼承性
只要基函數(shù)定義了virtual,繼承類的該函數(shù)也就具有virtual屬性
即 GrandFather Father Son同時定義virtual void fun()與GrandFather一個定義virtual void fun效果是一樣的

5.虛析構(gòu)函數(shù)

復制代碼 代碼如下:

class GrandFather
{
public:
 GrandFather() {}
 virtual void fun()
 {
  cout << "GrandFather call function!" << endl;
 }

 ~GrandFather()
 {
  cout << "GrandFather destruction!" << endl;
 }
};

class Father : public GrandFather
{
public:
 Father() {}
 void fun()
 {
  cout << "Father call function!" << endl;
 }

 ~Father()
 {
  cout << "Father destruction!" << endl;
 }
};


class Son : public Father
{
public:
 Son() {}
 void fun()
 {
  cout << "Son call function!" << endl;
 }

  ~Son()
 {
  cout << "Son destruction!" << endl;
 }
};

void print(GrandFather* p)
{
 p->fun();
}

int _tmain(int argc, _TCHAR* argv[])
{
 Father * pfather = new Son;
 delete pfather;
 return 0;
}


以上代碼輸出:Father destruction!
                             GrandFather destruction!
執(zhí)行了Son的構(gòu)造函數(shù),沒執(zhí)行Son的析構(gòu)函數(shù),故把GrandFather的析構(gòu)函數(shù)設置為virtual
則輸出: Son destruction!
        Father Destruction!
        GrandFather destruction!

6. 純虛函數(shù)
純虛函數(shù)定義如下:

復制代碼 代碼如下:

class GrandFather
{
public:
 GrandFather() {}
 virtual void fun() = 0
 {
  cout << "GrandFather call function!" << endl;
 }

 virtual ~GrandFather()
 {
  cout << "GrandFather destruction!" << endl;
 }
};


純虛函數(shù)為后代類提供可覆蓋的接口,但這個類中的版本決不會調(diào)用。
含有(或繼續(xù))一個或多個純虛函數(shù)的類是抽象基類,抽象基類不能實例化!
繼承類只有重寫這個接口才能被實例化


7.虛繼承
虛繼承主要解決交叉繼承帶來的問題。這里給出一片參考文章c++虛繼承。
給一個例子如下

復制代碼 代碼如下:

class GrandFather
{
public:
 GrandFather() {}
 void fun()
 {
  cout << "GrandFather call function!" << endl;
 }

 virtual ~GrandFather()
 {
  cout << "GrandFather destruction!" << endl;
 }
};

class Father1 : public GrandFather
{
public:
 Father1() {}
 void fun()
 {
  cout << "Father call function!" << endl;
 }
 
};

class Father2 : public GrandFather
{
public:
 Father2() {}
 void fun()
 {
  cout << "Father call function!" << endl;
 }

};


class Son : public Father1, public Father2
{
public:
 Son() {}
 //void fun()
 //{
 // cout << "Son call function!" << endl;
 //}
};

void print(GrandFather* p)
{
 p->fun();
}

int _tmain(int argc, _TCHAR* argv[])
{
 Son* son = new Son;
 son->fun();
 return 0;
}


編譯時會提示報錯對fun的訪問不明確
如果Father1和Father2都用虛繼承繼承GrandFather類則可以解決這個問題

8. 構(gòu)造函數(shù)和析構(gòu)函數(shù)中的虛函數(shù)
如果在構(gòu)造函數(shù)或析構(gòu)函數(shù)中調(diào)用虛函數(shù),則運行的是為構(gòu)造函數(shù)或析構(gòu)函數(shù)自身類型定義的版本


9.虛函數(shù)的實現(xiàn)機制
關于虛函數(shù)的實現(xiàn)機制,我們以后在介紹。

10.小結(jié)
關于virtual關鍵字的用法總結(jié)如上,有錯誤或者總結(jié)不到位的情況請能幫本人指出!

11.例子

復制代碼 代碼如下:

class classA
{
 public:
 classA()
 {
  clear();
 }
 virtual ~classA()
 {
 }
 void clear()
 {
  memset(this , 0 , sizeof(*this));
 }
 virtual void func()
 {
  printf("func\n");
 }
};

class classB : public classA
{
};

int main(void)
{
 classA oa;
 classB ob;
 classA * pa0 = &oa;
 classA * pa1 = &ob;
 classB * pb = &ob;
 oa.func(); // 1
 ob.func(); // 2
 pa0->func(); // 3
 pa1->func(); // 4
 pb->func(); // 5
 return 0;
}


補充一個例子,這個程序輸出依次是
func
func
出錯
func
func

談談我的理解,當
classA oa;
oa.func();
不存在動態(tài)調(diào)用的過程,所以func雖然是虛函數(shù),但是函數(shù)調(diào)用不通過虛表訪問,所以即使

復制代碼 代碼如下:

memset(this , 0 , sizeof(*this));

找不到虛表地址也沒有關系
在執(zhí)行classB ob;的時候,注意memset的是classA的地址,所有ob的虛表是存在的
即是如下,通過指針或引用(動態(tài)綁定)訪問oa的func函數(shù)(需要從虛表訪問),會出錯
訪問ob的func和函數(shù),無論靜態(tài)訪問還是動態(tài)訪問,都不會出錯


當把classB的代碼改成如下時

復制代碼 代碼如下:

class classB : public classA

<PRE style="FONT-WEIGHT: bold" class=cpp name="code">{</PRE><PRE style="FONT-WEIGHT: bold" class=cpp name="code">        classB()
 {
  clear();
 }
 virtual ~classB()
 {
 }
 void clear()
 {
     memset(this , 0 , sizeof(*this));
 }</PRE><BR>
<PRE></PRE>
<PRE style="FONT-WEIGHT: bold" class=cpp name="code">};</PRE>輸出為


func
func
出錯
出錯
出錯

相關文章

  • C++11標準庫bind函數(shù)應用教程

    C++11標準庫bind函數(shù)應用教程

    bind函數(shù)定義在頭文件functional中,可以將bind函數(shù)看做成一個通用的函數(shù)適配器,他接收一個可調(diào)用對象,生成一個新的可調(diào)用對象來"適應"原對象的參數(shù)列表。本文將帶大家詳細了解一下bind函數(shù)的應用詳解
    2021-12-12
  • C語言 socketpair用法案例講解

    C語言 socketpair用法案例講解

    這篇文章主要介紹了C語言 socketpair用法案例講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C語言中常量指針與指針常量區(qū)別淺析

    C語言中常量指針與指針常量區(qū)別淺析

    這篇文章主要介紹了C語言中常量指針與指針常量區(qū)別,有需要的朋友可以參考一下
    2013-12-12
  • C++中的函數(shù)匯總

    C++中的函數(shù)匯總

    這篇文章主要介紹了 C++中的函數(shù)匯總的相關資料,需要的朋友可以參考下
    2017-08-08
  • C++中繼承基類與派生類的區(qū)別

    C++中繼承基類與派生類的區(qū)別

    這篇文章主要介紹了C++中繼承基類與派生類的區(qū)別,面向?qū)ο蟪绦蛟O計中最重要的一個概念是繼承。繼承允許我們依據(jù)另一個類來定義一個類,這使得創(chuàng)建和維護一個應用程序變得更容易,需要的朋友可以參考下
    2023-05-05
  • C++11中的可變參數(shù)模板/lambda表達式

    C++11中的可變參數(shù)模板/lambda表達式

    C++11的新特性可變參數(shù)模板能夠讓我們創(chuàng)建可以接受可變參數(shù)的函數(shù)模板和類模板,相比C++98和C++03,類模板和函數(shù)模板中只能含固定數(shù)量的模板參數(shù),可變參數(shù)模板無疑是一個巨大的改進,這篇文章主要介紹了C++11中的可變參數(shù)模板/lambda表達式,需要的朋友可以參考下
    2023-03-03
  • Qt數(shù)據(jù)庫應用之通用數(shù)據(jù)庫同步

    Qt數(shù)據(jù)庫應用之通用數(shù)據(jù)庫同步

    數(shù)據(jù)庫同步的主要功能是將本地的數(shù)據(jù)庫記錄同步到遠程的數(shù)據(jù)庫。本文將利用Qt實現(xiàn)通用數(shù)據(jù)庫同步功能,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-03-03
  • C++ COM編程之QueryInterface函數(shù)(二)

    C++ COM編程之QueryInterface函數(shù)(二)

    這篇文章主要介紹了C++ COM編程之QueryInterface函數(shù)(二),本文是第二篇,第一篇請參閱相關文檔,需要的朋友可以參考下
    2014-10-10
  • tcp socket客戶端和服務端示例分享

    tcp socket客戶端和服務端示例分享

    這篇文章主要介紹了tcp socket客戶端和服務端示例,需要的朋友可以參考下
    2014-03-03
  • C++中register關鍵字舉例詳解

    C++中register關鍵字舉例詳解

    register用來聲明變量,然后聲明出來的變量是直接放在cpu的寄存器當中,而非就是通過內(nèi)存尋址訪問,這樣效率更高,下面這篇文章主要給大家介紹了關于C++中register關鍵字的相關資料,需要的朋友可以參考下
    2023-03-03

最新評論