虛函數(shù)是C++中用于實(shí)現(xiàn)多態(tài)(polymorphism)的機(jī)制。核心理念就是通過基類訪問派生類定義的函數(shù),虛函數(shù)只能借助于指針或者引用來達(dá)到多態(tài)的效果。
虛函數(shù)的語(yǔ)法:
1:class A{public: virtual void foo();};class B: public A{public: void foo(); // 沒有virtual關(guān)鍵字!};class C: public B // 從B繼承,不是從A繼承!{public: void foo(); // 也沒有virtual關(guān)鍵字!}; 這種情況下,B::foo()是虛函數(shù),C::foo()也同樣是虛函數(shù)。因此,可以說,基類聲明的虛函數(shù),在派生類中也是虛函數(shù),即使不再使用virtual關(guān)鍵字
2:純虛函數(shù):
一個(gè)函數(shù)聲明為純虛后,純虛函數(shù)的意思是:我是一個(gè)抽象類!不要把我實(shí)例化!純虛函數(shù)用來規(guī)范派生類的行為,實(shí)際上就是所謂的“接口”。它告訴使用者,我的派生類都會(huì)有這個(gè)函數(shù)。
3:純虛構(gòu)函數(shù):
當(dāng)一個(gè)類打算被用作其它類的基類時(shí),它的析構(gòu)函數(shù)必須是虛的。
4:虛構(gòu)造函數(shù):
構(gòu)造函數(shù)不能是虛的
5:虛函數(shù)使用技巧:
5.1:class A{public: void foo() { bar();}PRivate: virtual void bar() { ...}};class B: public A{private: virtual void bar() { ...}}; 在這個(gè)例子中,雖然bar()在A類中是private的,但是仍然可以出現(xiàn)在派生類中,并仍然可以與public或者protected的虛函數(shù)一樣產(chǎn)生多態(tài)的效果。并不會(huì)因?yàn)樗莗rivate的,就發(fā)生A::foo()不能訪問B::bar()的情況,也不會(huì)發(fā)生B::bar()對(duì)A::bar()的override不起作用的情況。這種寫法的語(yǔ)意是:A告訴B,你最好override我的bar()函數(shù),但是你不要管它如何使用,也不要自己調(diào)用這個(gè)函數(shù)。
5.2:構(gòu)造函數(shù)和析構(gòu)函數(shù)中的虛函數(shù)調(diào)用
一個(gè)類的虛函數(shù)在它自己的構(gòu)造函數(shù)和析構(gòu)函數(shù)中被調(diào)用的時(shí)候,它們就變成普通函數(shù)了,不“虛”了。也就是說不能在構(gòu)造函數(shù)和析構(gòu)函數(shù)中讓自己“多態(tài)”。例如:class A{public: A() { foo();} // 在這里,無論如何都是A::foo()被調(diào)用! ~A() { foo();} // 同上 virtual void foo();};class B: public A{public: virtual void foo();};void bar(){ A * a = new B; delete a;} 如果你希望delete a的時(shí)候,會(huì)導(dǎo)致B::foo()被調(diào)用,那么你就錯(cuò)了。同樣,在new B的時(shí)候,A的構(gòu)造函數(shù)被調(diào)用,但是在A的構(gòu)造函數(shù)中,被調(diào)用的是A::foo()而不是B::foo()。
參考:http://blog.csdn.net/bao_jinyu/article/details/7843275
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注