1,虚函数的定义,前面加个virtual
2,为什么要虚析构函数?
3,虚函数内存布局和原理探究。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Base
{
public:
virtual void func1(){
cout<<" Base func1 "<<endl;
}
virtual void func2(){
cout<<" Base func2 "<<endl;
}
virtual void func3(){
cout<<" Base func3 "<<endl;
}
protected:
private:
};
class Dog: public Base
{
public:
virtual void func1(){
cout<<" Dog func1 "<<endl;
}
protected:
private:
};
void main()
{
typedef void(*Fn)(void);
Dog mDog;
Base mBase;
Fn mFn = NULL;
cout<<"-----------------------------------------------------------------------"<<endl;
cout << "指向虚函数表的指针地址:" <<(int*)*(int*)(&mDog)<<"等同于:"<<hex<<*(int*)(&mDog)<<endl;
cout << "虚函数表 — 第一个函数地址:" <<"0x00"<< hex<<*((int*)*(int*)(&mDog) +0) << endl;
cout << "虚函数表 — 第2个函数地址:" << "0x00"<<hex<<*((int*)*(int*)(&mDog) +1) << endl;
cout << "虚函数表 — 第3个函数地址:" << "0x00"<<hex<<*((int*)*(int*)(&mDog) +2) << endl;
cout<<"-----------------------------------------------------------------------"<<endl;
mFn = (Fn)*((int*)*(int*)(&mDog) +0);
mFn();
getchar();
}
从图中可以看出来,当一个类有虚函数,则存在虚函数表,取类的在内存中的第一个地址(int*)&dog
, 这个地址里保存的是一个指向虚函数表的指针, 那么取该地址的值得到指向虚函数表的指针 :*(int*)(&dog)
;
所谓虚函数表就是一个指针数组,要取到指针数组的第一个元素, 即:
*(*(int*)(&dog)+ 0)
; 最后为了让这个地址以十六进制打印, 有以下两种方法:
方法一: cout<<hex<<*(*(int*)(&dog)+ 0)<<endl;
方法二: cout<< (int*) *(*(int*)(&dog)+ 0) <<endl;
那么第二个虚函数地址:*(*(int*)(&dog)+ 1)
第三个虚函数地址:*(*(int*)(&dog)+ 2)
示意图如下所示:
4,指向虚函数表的指针在类的内存布局的前面
5,c++多态的原因是? 子类的虚函数fun1()替换了父类的虚函数fun1()的位置。
6,参考https://blog.twofei.com/496/, 下面用c语言来默认c++的虚函数。
过程比较复杂,等我有时间再来弄吧。
7,哪些函数不能被定义为虚函数,为什么?
http://blog.csdn.net/hackbuteer1/article/details/6878255