class Person
{
virtual void Display () = 0; // 纯虚函数
protected :
string _name ; // 姓名
};
class Student : public Person
{};
上面概念大家可能都会问一句为什么要这样? 这些内容在接下来的知识里都能找到答案~ 好了那么我们今天的主角虚函数
登场!!!!何为虚函数表,我们写一个程序,调一个监视窗口就知道了。
下面是一个有虚函数的类:
#include
#include
using namespacestd;
class Base
{
public:
virtual void func1()
{}
virtual void func2()
{}
private:
inta;
};
void Test1()
{
Base b1;
}
int main()
{
Test1();
system("pause");
return0;
}
我们现在点开b1的监视窗口
这里面有一个_vfptr,而这个_vfptr指向的东西就是我们的主角,虚函数表。一会大家就知道了,无论是单继承还是多继
承甚至于我们的菱形继承虚函数表都会有不同的形态,虚函数表是一个很有趣的东西。
仔细看下面代码:
#include
#include
using namespace std;
class Base
{
public:
virtual void func1()
{
cout<< "Base::func1"<< endl;
}
virtual void func2()
{
cout<< "Base::func2"<< endl;
}
private:
inta;
};
class Derive:public Base
{
public:
virtual void func1()
{
cout<< "Derive::func1"<< endl;
}
virtual void func3()
{
cout<< "Derive::func3"<< endl;
}
virtual void func4()
{
cout<< "Derive::func4"<< endl;
}
private:
int b;
};
对于Derive类来说,我们觉得它的虚表里会有什么?
首先子类的fun1()重写了父类的fun1(),虚表里存的是子类的fun1(),接下来父类的fun2(),子类的fun3(),fun4()都是虚
函数,所以虚表里会有4个元素,分别为子类的fun1(),父类fun2(),子类fun3(),子类fun4()。然后我们调出监视窗口看
我们想的到底对不对呢?
我预计应该是看到fun1(),fun2(),fun3(),fun4()的虚函数表,但是呢这里监视窗口只有两个fun1(),fun2(),难道我们
错了?这里并不是这样的,只有自己靠得住,我觉得这里的编译器有问题,那我们就得自己探索一下了。 但是在探索之
前我们必须来实现一个可以打印虚函数表的函数。
typedef void(*FUNC)(void);
void PrintVTable(int* VTable)
{
cout<< " 虚表地址"<", i,VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout<< endl;
}
int main()
{
Derive d1;
PrintVTable((int*)(*(int*)(&d1)));
system("pause");
return0;
}
下图来说一下他的缘由:
我们来使用这个函数,该函数代码如下:
//单继承
class Base
{
public:
virtual void func1()
{
cout << "Base::func1" << endl;
}
virtual void func2()
{
cout << "Base::func2" << endl;
}
private:
int a;
};
class Derive :public Base
{
public:
virtual void func1()
{
cout << "Derive::func1" << endl;
}
virtual void func3()
{
cout << "Derive::func3" << endl;
}
virtual void func4()
{
cout << "Derive::func4" << endl;
}
private:
int b;
};
typedef void(*FUNC)(void);
void PrintVTable(int* VTable)
{
cout<< " 虚表地址"<", i,VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout<< endl;
}
int main()
{
Derive d1;
PrintVTable((int*)(*(int*)(&d1))); //重点
system("pause");
return0;
}
class Base1
{
public:
virtual void func1()
{
cout << "Base1::func1" << endl;
}
virtual void func2()
{
cout << "Base1::func2" << endl;
}
private:
int b1;
};
class Base2
{
public:
virtual void func1()
{
cout << "Base2::func1" << endl;
}
virtual void func2()
{
cout << "Base2::func2" << endl;
}
private:
int b2;
};
class Derive : public Base1, public Base2
{
public:
virtual void func1()
{
cout << "Derive::func1" << endl;
}
virtual void func3()
{
cout << "Derive::func3" << endl;
}
private:
int d1;
};
typedef void(*FUNC) ();
void PrintVTable(int* VTable)
{
cout << " 虚表地址>" << VTable << endl;
for (int i = 0; VTable[i] != 0; ++i)
{
printf(" 第%d个虚函数地址 :0X%x,->", i, VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout << endl;
}
void Test1()
{
Derive d1;
//Base2虚函数表在对象Base1后面
int* VTable = (int*)(*(int*)&d1);
PrintVTable(VTable);
int* VTable2 = (int *)(*((int*)&d1 + sizeof (Base1) / 4));
PrintVTable(VTable2);
}
int main()
{
Test1();
system("pause");
return 0;
}
//多态 析构函数
class Base
{
public:
virtual void func1()
{
cout << "Base::func1" << endl;
}
virtual void func2()
{
cout << "Base::func2" << endl;
}
virtual ~Base()
{
cout << "~Base" << endl;
}
private:
int a;
};
class Derive :public Base
{
public:
virtual void func1()
{
cout << "Derive::func1" << endl;
}
virtual ~Derive()
{
cout << "~Derive"<< endl;
}
private:
int b;
};
void Test1()
{
Base* q = new Derive;
delete q;
}
int main()
{
Test1();
system("pause");
return 0;
}