C++多态的实现原理是依赖虚指针来辨别具体使用家族类中的哪一个函数。以下就来证明虚指针的存在。
我们知道,指针的大小在一般情况下是4个字节,所以我们建立一个虚函数,再来计算该类的大小,便可以验证虚函数的存在。
代码如下:
#include <iostream>
using namespace std;
class A
{
public:
void print ()
{
}
private:
int a ;
};
class B
{
public:
virtual void print()
{
}
private:
int a ;
};
void main ()
{
cout << "sizeof(A)" << sizeof( A) << endl ;
cout << "sizeof(B)" << sizeof( B) << endl ;
system("pause" );
}
运行结果:
A类与B类的,唯一差别就是在B类中 print()变成了一个虚函数,实验结果看到B类却比A类多出了4个字节,那说明在B类中,编译器隐藏的添加了一个虚指针的成员变量。
接下来在验证,一个类中,有多个虚函数,会不会分配多个虚指针:
#include <iostream>
using namespace std;
class B
{
public:
virtual void print()
{
}
virtual void print2()
{
}
private:
int a ;
};
void main ()
{
cout << "sizeof(B)" << sizeof( B) << endl ;
system("pause" );
}
运行结果:
这就说明了,一个类中不管有几个虚函数,都只会生成一个虚指针变量。
这个虚指针变量实质上是指向一个虚函数表。我们先来看下什么是虚函数表。
虚函数表定义:
类的虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址。注意的是,编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享。类的每个虚成员占据虚函数表中的一行。如果类中有N个虚函数,那么其虚函数表将有N*4字节的大小。也就是说虚函数表是一块连续的内存,每一个虚成员,都会占据一块内存空间。
在平时设计代码是如果明确不需要使用虚函数,那就不要随便使用:
1 主要原因是,虚指针调用虚函数是在程序运行时进行的,所以需要通过寻址操作才能找到真正应该调用的函数,而普通成员函数是在编译时就确定了调用的函数,不需要寻址操作,因此在效率上,虚函数的效率要低很多。
2 其次,因为他会在虚函数表中多占据一块内存空间,浪费空间。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-14 11:16:45