亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

c++ 虛函數與純虛函數的區別(深入分析)

2020-01-26 16:05:08
字體:
來源:轉載
供稿:網友
在面向對象的C++語言中,虛函數(virtual function)是一個非常重要的概念。因為它充分體現 了面向對象思想中的繼承和多態性這兩大特性,在C++語言里應用極廣。比如在微軟的MFC類庫中,你會發現很多函數都有virtual關鍵字,也就是說, 它們都是虛函數。難怪有人甚至稱虛函數是C++語言的精髓。
那么,什么是虛函數呢,我們先來看看微軟的解釋:
虛函數是指一個類中你希望重載的成員函數,當你用一個基類指針或引用指向一個繼承類對象的時候,你調用一個虛函數,實際調用的是繼承類的版本。                                                          這個定義說得不是很明白。MSDN中還給出了一個例子,但是它的例子也并不能很好的說明問題。我們自己編寫這樣一個例子:
復制代碼 代碼如下:

#include "stdio.h"
#include "conio.h"
class Parent
{    
public:
    char data[20];    
    void Function1();
    virtual void Function2(); // 這里聲明Function2是虛函數    
}parent;
void Parent::Function1()
{
    printf("This is parent,function1/n");
}
void Parent::Function2()
{
    printf("This is parent,function2/n");
}
class Child: public Parent
{
    void Function1();
    void Function2();

} child;
void Child::Function1()
{
    printf("This is child,function1/n");
}
void Child::Function2()
{
    printf("This is child,function2/n");
}
int main(int argc, char* argv[])
{    
    Parent *p; // 定義一個基類指針    

    if ( _getch()=='c' ) // 如果輸入一個小寫字母c
        p=&child; // 指向繼承類對象
    else
        p=&parent; // 否則指向基類對象

    p->Function1(); // 這里在編譯時會直接給出Parent::Function1()的 入口地址。   
    p->Function2(); // 注意這里,執行的是哪一個Function2?

    return 0;
}

用任意版本的Visual C++或Borland C++編譯并運行,輸入一個小寫字母c,得到下面的結果:
This is parent,function1
This is child,function2
為什么會有第一行的結果呢?因為我們是用一個Parent類的指針調用函數Fuction1(),雖然實際上這個指針指向的是Child類的對象,但編譯器 無法知道這一事實(直到運行的時候,程序才可以根據用戶的輸入判斷出指針指向的對象),它只能按照調用Parent類的函數來理解并編譯,所以我們看到了 第一行的結果。
  
那么第二行的結果又是怎么回事呢?我們注意到,Function2()函數在基類中被virtual關鍵字修飾,也就是 說,它是一個虛函數。虛函數最關鍵的特點是“動態聯編”,它可以在運行時判斷指針指向的對象,并自動調用相應的函數。如果我們在運行上面的程序時任意輸入 一個非c的字符,結果如下:
This is parent,function1
This is parent,function2
  
請注意看第二行,它的結果出現了變化。程序中僅僅調用了一個Function2()函數,卻可以根據用戶的輸入自動決定到底調用基類中的Function2 還是繼承類中的Function2,這就是虛函數的作用。我們知道,在MFC中,很多類都是需要你繼承的,它們的成員函數很多都要重載,比如編寫MFC應 用程序最常用的CView::OnDraw(CDC*)函數,就必須重載使用。把它定義為虛函數(實際上,在MFC中OnDraw不僅是虛函數,還是純虛 函數),可以保證時刻調用的是用戶自己編寫的OnDraw。虛函數的重要用途在這里可見一斑。
-----------------------------------------------------------
再看下面的
派生類的大小問題C++中虛函數和純虛函數的概念,差別和分別存在的原因
首先:強調一個概念
定義一個函數為虛函數,不代表函數為不被實現的函數,定義它為虛函數是為了允許用基類的指針來調用子類的這個函數
定義一個函數為純虛函數,才代表函數沒有被實現,定義他是為了實現一個接口,起到一個規范的作用,規范繼承這個類的程序員必須實現這個函數。
對繼承的影響:
普通的類(沒有虛函數,純虛函數)就可以被繼承,而且工作的相當好
關于這個問題有以下疑問:
純虛函數難道就是為了實現接口?接口存在的意義?
我實在弄不懂,我干嘛要預先定義好?未來的事情本難料,就等有一天我的類中需要使用某個函數,在添加一個函數不就可以?
關于實例化一個類:
有純虛函數的類是不可能生成類對象的,如果沒有純虛函數則可以。比如:
復制代碼 代碼如下:

class CA
{
public:
    virtual void fun() = 0; // 說明fun函數為純虛函數
    virtual void fun1();
};
class CB
{
public:
    virtual void fun();
    virtual void fun1();
};
// CA,CB類的實現
...
void main()
{
    CA a; // 不允許,因為類CA中有純虛函數
    CB b; // 可以,因為類CB中沒有純虛函數

    ...
}

---------------------------------------------------------------
虛函數在多態中間的使用:
多態一般就是通過指向基類的指針來實現的。
dog mydogwangwang;
mydogwangwang.born();
一定是返回“dog”
那么
horse myhorsepipi;
myhorsepipi.born();
一定是返回“horse”
也是多態呀?
/////////////////////////////////////////////////
有一點你必須明白,就是用父類的指針在運行時刻來調用子類:
例如,有個函數是這樣的:
復制代碼 代碼如下:

void animal::fun1(animal *maybedog_maybehorse)
{
     maybedog_maybehorse->born();
}

參數maybedog_maybehorse在編譯時刻并不知道傳進來的是dog類還是horse類,所以就把它設定為animal類,具體到運行時決定了才決定用那個函數。
也就是說用父類指針通過虛函數來決定運行時刻到底是誰而指向誰的函數。
復制代碼 代碼如下:

//用虛函數
#include <iostream.h>
class animal
{
public:
    animal();
    ~animal();
    void fun1(animal *maybedog_maybehorse);
    virtual void born();
};
void animal::fun1(animal *maybedog_maybehorse)
{
    maybedog_maybehorse->born();
}
animal::animal()
{
}
animal::~animal()
{
}
void animal::born()
{
    cout<< "animal";
}
class dog: public animal
{
public:
    dog();
    ~dog();
    virtual void born();
};
dog::dog()
{
}
dog::~dog()
{
}
void dog::born()
{
    cout<<"dog";
}
class horse:public animal
{
public:
    horse();
    ~horse();
    virtual void born();
};
horse::horse()
{
}
horse::~horse()
{
}
void horse::born()
{
    cout<<"horse";
}
void main()
{
    animal a;
    dog b;
    horse c;    
    a.fun1(&c);
}
//output: horse
//不用虛函數
#include <iostream.h>
class animal
{
public:
    animal();
    ~animal();
    void fun1(animal *maybedog_maybehorse);
    void born();    
};
void animal::fun1(animal *maybedog_maybehorse)
{
    maybedog_maybehorse->born();
}
animal::animal()
{
}
animal::~animal()
{
}
void animal::born()
{
    cout<< "animal";
}
class dog: public animal
{
public:
    dog();
    ~dog();
    void born();
};
dog::dog()
{
}
dog::~dog()
{
}
void dog::born()
{
    cout<<"dog";
}
class horse:public animal
{
public:
    horse();
    ~horse();
    void born();
};
horse::horse()
{
}
horse::~horse()
{
}
void horse::born()
{
    cout<<"horse";
}
void main()
{
    animal a;
    dog b;
    horse c;    
    a.fun1(&c);
}
//output: animal

---------------------------------------------------------------
有純虛函數的類是抽象類,不能生成對象,只能派生。他派生的類的純虛函數沒有被改寫,那么,它的派生類還是個抽象類。
---------------------------------------------------------------
定義純虛函數就是為了讓基類不可實例化化,
因為實例化這樣的抽象數據結構本身并沒有意義.
或者給出實現也沒有意義
實際上我個人認為純虛函數的引入,是出于兩個目的:
1.為了安全.因為避免任何需要明確但是因為不小心而導致的未知的結果. 提醒子類去做應做的實現.
2.為了效率,不是程序執行的效率,而是為了編碼的效率.
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美成人精品在线视频| 丝袜亚洲另类欧美重口| 欧美裸体xxxx极品少妇软件| 成人久久18免费网站图片| www.久久撸.com| 一本色道久久综合狠狠躁篇的优点| 久久精品99国产精品酒店日本| 国产精品久久91| 亚洲成人av在线| 亚洲自拍欧美另类| 青青青国产精品一区二区| 欧美日韩在线另类| 日av在线播放中文不卡| 亚洲欧洲日本专区| 色阁综合伊人av| 日韩成人中文字幕| 日韩av电影中文字幕| 欧美夜福利tv在线| 国产一区二区三区在线观看网站| 日韩av在线免费观看| 欧美国产日韩视频| 日韩网站在线观看| 久久综合电影一区| 91久久久久久久久久久久久| 日韩视频在线观看免费| 亚洲国产成人久久| 国产在线a不卡| 清纯唯美亚洲综合| 国产精选久久久久久| 日韩精品视频在线观看免费| 色综合影院在线| 亚洲精品www久久久| 国产精品视频久久| 成人av资源在线播放| 另类天堂视频在线观看| 欧美黑人性生活视频| 欧美激情在线视频二区| 中文字幕av一区二区三区谷原希美| 91国产精品电影| 国产精品久久久久久久一区探花| 欧美性xxxx极品hd满灌| 国产精品视频一区二区高潮| 国产精品日韩欧美大师| 欧美裸体xxxxx| 日韩av色在线| 欧美午夜美女看片| 欧美成人精品激情在线观看| 国产精品视频免费在线| 2020国产精品视频| 国产精品扒开腿做爽爽爽视频| 亚洲欧美日韩国产精品| 国产精品狼人色视频一区| 精品一区二区三区四区在线| 国产精品电影网站| 综合网日日天干夜夜久久| 久久免费国产精品1| 少妇精69xxtheporn| 韩国视频理论视频久久| 自拍亚洲一区欧美另类| 国产欧美精品在线播放| 亚洲第一福利网站| 北条麻妃在线一区二区| 亚洲一区第一页| 久久久久久久久久久国产| 日本一区二三区好的精华液| 日韩va亚洲va欧洲va国产| 午夜精品福利视频| 亚洲的天堂在线中文字幕| 国产97免费视| 亚洲人成免费电影| 欧美第一页在线| 成人免费xxxxx在线观看| 国产脚交av在线一区二区| 成人午夜两性视频| 国产一区二区三区在线看| 精品国产欧美一区二区五十路| 有码中文亚洲精品| 久久韩国免费视频| 日韩免费在线免费观看| 欧美性xxxxx极品娇小| 国产成人高清激情视频在线观看| 国产伦精品免费视频| 97在线精品国自产拍中文| 中文精品99久久国产香蕉| 欧美日产国产成人免费图片| 爱福利视频一区| 国产偷亚洲偷欧美偷精品| 欧美电影在线观看完整版| 日韩有码在线观看| 国产偷国产偷亚洲清高网站| 亚洲国产日韩欧美在线动漫| 欧美日韩在线免费| 欧美xxxx14xxxxx性爽| 欧美日本高清一区| 欧美大尺度在线观看| 成人激情免费在线| 2019中文字幕在线| 精品亚洲精品福利线在观看| 久久久久久久久久久免费| 国产亚洲精品一区二区| 91精品国产综合久久久久久蜜臀| 国产一区二区欧美日韩| 国产精品高清在线| 91精品国产高清久久久久久91| 色噜噜国产精品视频一区二区| 日韩精品极品视频免费观看| 精品久久久91| 97在线观看免费| 久久五月天色综合| 欧美亚洲视频在线观看| 精品久久久久久久久久ntr影视| 伊人亚洲福利一区二区三区| 久久亚洲精品一区| 69国产精品成人在线播放| 国产日韩中文字幕在线| 2021久久精品国产99国产精品| 97精品国产91久久久久久| 日本一区二区三区四区视频| 青青青国产精品一区二区| 最近中文字幕2019免费| 久久久久久香蕉网| 色综合视频一区中文字幕| 国产一区二区三区日韩欧美| 欧美性视频精品| 亚洲va欧美va国产综合剧情| 岛国av一区二区在线在线观看| 国产精品美女久久| 91沈先生在线观看| 红桃视频成人在线观看| 欧美日韩中文字幕综合视频| 狠狠躁夜夜躁人人爽天天天天97| 欧美成人激情视频免费观看| 欧美亚洲成人精品| 成人精品一区二区三区电影免费| 久久久久久久久久久久av| 最近2019中文免费高清视频观看www99| 欧美限制级电影在线观看| 日韩免费精品视频| 国产精品美女久久久久av超清| 中文字幕亚洲欧美一区二区三区| 精品国产福利视频| 国产欧美日韩视频| 精品偷拍一区二区三区在线看| 亚洲自拍在线观看| 日本高清不卡在线| 欧美理论片在线观看| 亚洲国产精品免费| 91国产一区在线| 青青在线视频一区二区三区| 日韩欧美第一页| 这里只有精品久久| 午夜精品在线观看| 深夜精品寂寞黄网站在线观看| 欧美激情视频一区二区三区不卡| 亚洲网站在线观看| 韩国19禁主播vip福利视频| 国产日韩欧美在线看| 亚洲国产日韩欧美综合久久| 亚洲а∨天堂久久精品9966| 亚洲成人网在线| 成人黄色午夜影院| 色一区av在线| 欧美性jizz18性欧美| 欧美日韩国产成人高清视频|