导航:首页 > 源码编译 > 虚函数表编译器如何实现

虚函数表编译器如何实现

发布时间:2023-03-27 16:01:02

Ⅰ C++虚表问题

虚函数表是编译器用来实现多态的方法。一般来说,虚函数表是一个数组,数组的元素是虚函数的指针。每个对象都会有一个虚函数表,当在某个对象上调用虚函数时,通过查询这个表来获得继承层次中到底哪个函数被实际调用。
对于一个类如果有虚函数,就会在这个类中创建一个虚表,也就会产生一个虚指针指向这个虚表。
既然有一个指针指向了虚表,这个类派生后,在派生类中就不必再创建虚表,如果派生类还有自己的虚函数,那么只在派生类中创建该虚函数的一个虚表,产生一个指向该虚表的指针。
为每个类设置虚表,初始化虚指针,为虚函数调用插入代码都是自动发生的,不必担心这些。

(我看到过虚继承下虚表问题的分析,直接继承下没看过,特此又分析了一下,修改)
#include<iostream>
using namespace std;
class A
{

public:
virtual void a(){};
};
class B:public virtual A
{

public:
virtual void b(){};

};

int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
}

对于这个程序,你大概是在vc6.0下运行的吧,在vc下结果是4和12。我用的编译器是g++,对于这段程序的结果确实都为4.

因编译器不同导致结果不同这个我倒是没注意,这样可以得出,对虚函数这里的处理机制和编译器也是有关的,g++编译器还是更符合新的标准。

把虚继承virtual去掉再运行,在codeblocks下,g++编译运行结果都为4. vc下编译运行结果也都为4.

在分析一个例子:
#include<iostream>
using namespace std;
class A
{
char j[3];
public:
virtual void a(){};
};
class B:public A
{
char k[3];
public:
virtual void b(){};

};
class C:public B
{
char m[3];
public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
这个直接继承的例子,在vc下,codeblocks下结果都为 8 12 16.

再看这个直接继承的例子:
#include<iostream>
using namespace std;
class A
{

public:
virtual void a(){};
};
class B:public A
{

public:
virtual void b(){};

};
class C:public B
{

public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
vc下河codeblocks下结果都为 4. 这两个程序说明,直接继承下,输出结果应当是本类所占的字节加父类数据成员所占字节,父类的虚指针所占字节没有加上。

加入虚继承后:
#include<iostream>
using namespace std;
class A
{
char j[3];
public:
virtual void a(){};
};
class B:public virtual A
{
char k[3];
public:
virtual void b(){};

};
class C:public virtual B
{
char m[3];
public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
这段代码,在codeblocks下g++编译运行结果为:8 16 24.
在vc6.0下编译运行结果为:8 20 32.
能够分析出codeblocks下的结果是本类加上父类的结果。vc下是 本类加父类后又加了4个字节。

但是这段代码:
#include<iostream>
using namespace std;
class A
{

public:
virtual void a(){};
};
class B:public virtual A
{

public:
virtual void b(){};

};
class C:public virtual B
{

public:
virtual void c(){};
};
int main()
{
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
}
codeblocks下编译运行结果为 4 4 4.
vc下编译运行结果为:4 12 20.
从结果来看,vc下是 本类加父类后又加了4个字节。而codeblocks结果就不再是本类加父类的结果(这个有点迷茫)。

阅读全文

与虚函数表编译器如何实现相关的资料

热点内容
ca证书加密机价格 浏览:798
天干地支年份算法 浏览:796
程序员打造的视频 浏览:6
java和php通信 浏览:679
为什么黑程序员 浏览:162
程序员男生 浏览:455
戴尔文件夹内文件怎么置顶 浏览:582
云服务器6m网速 浏览:722
vivo手机中国联通服务器地址 浏览:862
工程总控编译失败 浏览:706
燕赵红枫app如何下载 浏览:867
php查杀软件 浏览:878
教育管理学pdf 浏览:547
服务器均衡怎么使用 浏览:626
linux中jps 浏览:954
单片机实验感想 浏览:561
程序员级别数学算法逻辑 浏览:900
2k21公园怎么换服务器 浏览:724
php释放数据库连接 浏览:722
php网页抓取工具 浏览:726