资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

虚函数和虚拟继承的内存分布-创新互联

一.虚函数

成都创新互联公司服务紧随时代发展步伐,进行技术革新和技术进步,经过十年的发展和积累,已经汇集了一批资深网站策划师、设计师、专业的网站实施团队以及高素质售后服务人员,并且完全形成了一套成熟的业务流程,能够完全依照客户要求对网站进行成都网站设计、成都做网站、建设、维护、更新和改版,实现客户网站对外宣传展示的首要目的,并为客户企业品牌互联网化提供全面的解决方案。

(1)C++中的虚函数的主要作用:实现了多态的机制。

(2)多态:用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

(3)多态要基于函数重载,所以如果子类没有重载父类的虚函数那是一件毫无意义的事情。

二.虚函数表

1.虚函数表:虚函数表C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

如图:

虚函数和虚拟继承的内存分布

虚函数表的最后多加了一个结点,这是虚函数表的结束结点,就像字符串的结束符“/0”一样,其标志了虚函数表的结束。这个结束标志的值在不同的编译器下是不同的。在WinXP+VS2003下,这个值是NULL。而在Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3下,这个值是如果1,表示还有下一个虚函数表,如果值是0,表示是最后一个虚函数表。

2.虚函数在虚函数表中的存放原则

1)虚函数按照其声明顺序放于表中。

2)父类的虚函数在子类的虚函数前面

3)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。

4)没有被覆盖的函数依旧。

虚函数和虚拟继承的内存分布

3.多重继承

1) 每个父类都有自己的虚表。

2) 子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)   这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

虚函数和虚拟继承的内存分布

三.进阶

(1)单一的一般继承

1)虚函数表在最前面的位置。

2)成员变量根据其继承和声明顺序依次放在后面。

3)在单一的继承中,被重写的虚函数在虚函数表中得到了更新。

虚函数和虚拟继承的内存分布x

(2)多重继承(只是比上面的多重继承多了个成员变量)

1)每个父类都有自己的虚表。

2)子类的成员函数被放到了第一个父类的表中。

3)内存布局中,其父类布局依次按声明顺序排列。

4)每个父类的虚表中的f()函数都被重写成了子类的f()。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

虚函数和虚拟继承的内存分布

(3)重复继承

虚函数和虚拟继承的内存分布

最顶端的父类B其成员变量存在于B1和B2中,并被D给继承下去了。而在D中,其有B1和B2的实例,于是B的成员在D的实例中存在两份,一份是B1继承而来的,另一份是B2继承而来的。所以,如果我们使用以下语句,则会产生二义性编译错误:

D d;
d.ib = 0; //二义性错误
d.B1::ib = 1; //正确
d.B2::ib = 2; //正确

注意,上面例程中的最后两条语句存取的是两个变量。虽然我们消除了二义性的编译错误,但B类在D中还是有两个实例,这种继承造成了数据的重复,我们叫这种继承为重复继承。重复的基类数据成员可能并不是我们想要的。所以,C++引入了虚基类的概念。

(4)重复虚拟继承-把上述的“重复继承”的B1和B2继承B的语法中加上virtual 关键,就成了虚拟继承

虚函数和虚拟继承的内存分布

四.利用虚函数表做的坏事儿

(1)任何试图使用父类指针调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法,但我们可以通过指针的方式访问虚函数表来达到违反C++语义的行为。

(2)如果父类的虚函数是private或是protected的,但这些非public的虚函数同样会存在于虚函数表中,所以,我们同样可以使用访问虚函数表的方式来访问这些non-public的虚函数。

<有个疑惑:为什么最后一个多重虚继承B的地址在最后?请大家指教一下,我也下去再好好研究一下>

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享名称:虚函数和虚拟继承的内存分布-创新互联
文章链接:http://cdkjz.cn/article/ippii.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220