轉載請註明t1234xy4原創:http://blog.csdn.net/t1234xy4/article/details/51191270
《C++ Primer》書上學習得到的基礎:
純虛函數:
1、純虛函數只聲明,沒有定義。書寫=0說明爲純虛函數。
2、含有純虛函數的內,稱爲抽象基類,所謂抽象基類只負責定義接口,後續的其他類可以覆蓋該接口,我們不能創建抽象基類的實例。
3、能夠被覆蓋。
普通虛函數:
1、聲明爲普通函數前加virtual,不僅要申明,而且必須定義。
2、能夠被覆蓋。(只有虛函數能夠被覆蓋)
測試虛函數與純虛函數區別:
測試1、測試純虛函數能不能有重名而函數個數不同的重載:
//virtualBase.hxx:
#include <string>
#include <iostream>
#pragma once
using namespace std;
class VirtualBase
{
public:
VirtualBase(void);
virtual void helloword(string s)=0;
virtual void helloword(string s1,string s2)=0;
~VirtualBase(void);
};
virtualclass 繼承了virtualBase
VirtualClass.hxx :
#pragma once
#include "virtualbase.h"
#include "VirtualBaseCopy.h"
class VirtualClass :
public VirtualBase/*,public VirtualBaseCopy*/
{
public:
VirtualClass(void);
virtual void helloword(string s);
virtual void helloword(string s1,string s2);
~VirtualClass(void);
};
virtualclass.c
#include "StdAfx.h"
#include "VirtualClass.h"
void VirtualClass::helloword(string s1,string s2)
{
cout << "VirtualClass: hello ,"<<s1 <<","<<s2<<endl;
}
void VirtualClass::helloword(string s)
{
cout << "virtualclass: hello,"<<s<<endl;
}
Main.c:
int _tmain(int argc, _TCHAR* argv[])
{
**VirtualBase *base = new VirtualClass; //注意此處**
string s = "jack";
string s2 = "rose";
base->helloword(s,s2);
base->helloword(s);
while (1){}
return 0;
}
執行結果如下:
測試1結論:如果基類擁有重載純虛函數接口,子類分別實例化後可用。也就是說,子類重寫的兩個函數分別覆蓋了基類的兩個函數。
測試2:如果基類VirtualBase中只有其中一個接口?,子類中是否可以出現同名的函數。
修改VirtualBase.hxx如下:
#include <string>
#include <iostream>
#pragma once
using namespace std;
class VirtualBase
{
public:
VirtualBase(void);
//virtual void helloword(string s)=0;
virtual void helloword(string s1,string s2)=0;
~VirtualBase(void);
};
int _tmain(int argc, _TCHAR* argv[])
{
**VirtualClass *base = new VirtualClass;**//注意此處
string s = "jack";
string s2 = "rose";
base->helloword(s,s2);
base->helloword(s);
//cout<<base->add(2,3);
while (1){}
return 0;
}
結果:
修改爲下面的後:
**VirtualBase *base = new VirtualClass;**//注意此處
編譯不通過。
測試2結論:
1、編譯不通過在情理之中,基類的指針開闢的空間結構不具有另一個函數的指針。
2、helloword(string s1,string s2)是VirtualClass的虛函數可行,運行沒有問題。也就是說,子類可以出現與父類接口同名的函數。
虛函數是可以連續繼承的。也就是說,一個函數在基類中爲虛函數,那麼在他的子子孫孫類中都是虛函數。
測試3: VirtualClass的子類還能否夠繼承他
我們添加類VirtualConcreate繼承VirtualClass類,並重寫虛函數helloword(string s):
void VirtualConcreate::helloword(string s)
{
cout<<"concrete:hello,"<<s<<endl;
}
實例化如下:
**VirtualBase *base = new VirtualConcreate;**
結果如下:
測試3結論如下:
1、如果在VirtualConcrete類中,函數中重寫了父類的虛函數,那麼父類的虛函數將被覆蓋掉;
2、子類中沒有重寫的父類函數,直接調用父類函數;
測試4:基類的接口,在其派生類中出現了與接口同名(函數個數不同或者參數不同)的虛函數是否一起被繼承。
測試4結論:可以一起被繼承。
測試總結:虛函數也可用重載,純虛函數一樣可以重載。,只有形參類型完全相同的虛函數纔會被覆蓋!!
測試5:普通成員函數與虛函數區別。
虛函數:
1、只有虛函數才能被覆蓋(《C++ primer(第5版)》 538頁)
2、虛函數是動態綁定
成員函數:
1、成員函數是靜態綁定