⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subject_27845.htm

📁 vc
💻 HTM
字号:
<p>
序号:27845 发表者:tigersky2000 发表日期:2003-01-15 20:41:38
<br>主题:虚继承的迷惑,请熟悉MI的朋友帮忙看看
<br>内容:在看多重继承时出现一个问题<BR><BR>如下程序,其中base是基类,novirtual_deliver为正常的派生类,virtual_deliver为虚派生类<BR><BR>最后运行结果是<BR><BR>sizeof(b)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<BR>sizeof(nv)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4<BR>sizeof(vd1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8<BR><BR>b和nv都是4byte可以理解,因为这是一个vtable指针的大小,但是vd1的大小为8,我却不知道多出来的四个字节是什么(和书上说的一样,会<BR><BR>多出字节),于是我就调试下面的程序看看,结果在调试窗口(见图)里却看不出来多出来的4byte是什么?<BR><BR><BR>#include &lt;iostream.h&gt;<BR><BR>class base <BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void f(){cout&lt;&lt;"base"&lt;&lt;endl;}<BR>};<BR><BR>class novirtual_deliver : public base{};<BR><BR>class virtual_deliver1: virtual public base{};<BR><BR>#define write(par) cout&lt;&lt;#par&lt;&lt;"\t\t"&lt;&lt;par&lt;&lt;endl;<BR><BR><BR>void main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;base b;<BR>&nbsp;&nbsp;&nbsp;&nbsp;novirtual_deliver nv;<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual_deliver1 vd1;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(b))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(nv))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(vd1))<BR><BR>}<BR><BR><BR>请大家帮忙看看! 虚派生类比基类大,大在什么地方,另从如果有两个从base中来的virtual_deliver1这样的虚派生类,我用这两个类多重<BR><BR>继承一个新类,这个新类的大小为12,这又是为什么?<BR>
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:dr0 回复日期:2003-01-15 20:56:08
<br>内容:1: 应该是多出vptr<BR>2: 12是因为,两个virtual_deliver每个含有一个vptr, 因为<BR>&nbsp;&nbsp; 生成上面两个多承继承的类时,只有一个base object,存在,<BR>&nbsp;&nbsp; 所以,有 a::vptr + b::vptr + c::vptr==12, c 是多承继承出来的类。<BR><BR>virtual inherence 极少用到,你可以看看Stan Leppman 的 Inside The C++ Object Model,里面有介绍。我日子久了,也记不清了。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dr0 回复日期:2003-01-15 21:00:36
<br>内容:唉,现在在网吧里,也没法实际调试一下,抱歉了,你仔细看看<BR>vd1的头4个字节指向谁,下面的4个字节指向谁。<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-15 21:02:48
<br>内容:可是在图中,我只看到一个vptr呀,即图中的vd1---&gt;base---&gt;__vfptr,如果有第二个的话,也应该在里面呀! 而且,我设想这个vptr应该在vd1---&gt;__vfptr,表示是vd1的vfptr
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dr0 回复日期:2003-01-15 21:06:58
<br>内容:novirtual_deliver<BR>和virtual_deliver1 MI一下,贴出 memory layout 来看看。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-15 21:20:31
<br>内容:马上贴出来! 先看看我的想法,在图上<BR><BR>另外,我看了vd1有两个指针,第一个指向的地址的值是0<BR>第二个指向了base vfptr
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-15 21:24:33
<br>内容:MI memory
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-15 21:26:30
<br>内容:#include &lt;iostream.h&gt;<BR><BR>class base <BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void f(){cout&lt;&lt;"base"&lt;&lt;endl;}<BR>};<BR><BR>class novirtual_deliver : public base{};<BR><BR>class virtual_deliver1: virtual public base{public: int i;};<BR><BR>#define write(par) cout&lt;&lt;#par&lt;&lt;"\t\t"&lt;&lt;par&lt;&lt;endl;<BR><BR><BR>class temp : public novirtual_deliver,public virtual_deliver1{};<BR><BR>void main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;base b;<BR>&nbsp;&nbsp;&nbsp;&nbsp;novirtual_deliver nv;<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual_deliver1 vd1;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;temp t;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;&amp;t&lt;&lt;endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(b))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(nv))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(vd1))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(t))<BR>}<BR><BR>运行结果:<BR><BR>0x0012FF5C<BR>sizeof(b)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<BR>sizeof(nv)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4<BR>sizeof(vd1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12<BR>sizeof(t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dr0 回复日期:2003-01-15 21:39:26
<br>内容:每个类里加个数据成员试试。<BR>我记得think in c++里也有讲到virtual inheritance 问题,<BR>不同编译器好像实现方式还不同,你看看吧,应该在<BR>virtual function那一章的末尾
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:dr0 回复日期:2003-01-15 21:41:01
<br>内容:至于为什么是这种layout,我现在也不晓得了。:(, 忘了。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-15 21:43:12
<br>内容:我就是看这本书,才出现这个问题的<BR><BR>0x0012FF40<BR>sizeof(b)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8<BR>sizeof(nv)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12<BR>sizeof(vd1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16<BR>sizeof(t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 28<BR><BR>程序<BR>#include &lt;iostream.h&gt;<BR><BR>class base <BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;int k;<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void f(){cout&lt;&lt;"base"&lt;&lt;endl;}<BR>};<BR><BR>class novirtual_deliver : public base{int j;};<BR><BR>class virtual_deliver1: virtual public base{public: int m;};<BR><BR>#define write(par) cout&lt;&lt;#par&lt;&lt;"\t\t"&lt;&lt;par&lt;&lt;endl;<BR><BR><BR>class temp : public novirtual_deliver,public virtual_deliver1{};<BR><BR>void main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;base b;<BR>&nbsp;&nbsp;&nbsp;&nbsp;novirtual_deliver nv;<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual_deliver1 vd1;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;temp t;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;&amp;t&lt;&lt;endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(b))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(nv))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(vd1))<BR>&nbsp;&nbsp;&nbsp;&nbsp;write(sizeof(t))<BR>}<BR><BR>memory图<BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:IceAge 回复日期:2003-01-15 22:55:20
<br>内容:派生类从 虚 基类进行多重继承时,除了嵌入基类,还需嵌入一个表指针,以保存各个基类的偏移地址,以便可以正确地向上强制,同时也解决了使用共同基类所产生的歧义。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:IceAge 回复日期:2003-01-16 00:17:21
<br>内容:补充<BR>考虑如下情况:<BR><BR>class base { public: int data; };<BR>clase A : public virtual base { };<BR>class B : public virtual base { };<BR>class C : public virtual A, public virtual B { };<BR><BR>void main() {<BR>&nbsp;&nbsp; C c;<BR>&nbsp;&nbsp; c.data = 1;<BR>&nbsp;&nbsp; A* pa = &amp;c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//向上强制<BR>&nbsp;&nbsp; B* pb = &amp;c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //向上强制<BR>&nbsp;&nbsp; base* pbase = &amp;c;&nbsp;&nbsp;&nbsp;&nbsp; //向上强制<BR>&nbsp;&nbsp; printf("%d, %d, %d, %d", c.data, pa-&gt;data, pb-&gt;data, pbase-&gt;data);<BR>}<BR><BR>尽管从A, B 继承, c中只有一份 base 的 data, A, B 共享(不是分别嵌入)这个 data, 因而A, B 中必须能够知道如何存取这个共享的 data, 所以A, B 中需要数据的 virtual table 来正确的存取数据。<BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:雍菲 回复日期:2003-01-16 10:55:02
<br>内容:能够讲讲何为虚继承?<BR>请各位大虾.........
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:tigersky2000 回复日期:2003-01-16 12:59:57
<br>内容:to IceAge<BR><BR>我在A中加了一个变量,我的分析与不解都在图里呢<BR><BR>#include &lt;iostream.h&gt;<BR>#include &lt;stdio.h&gt;<BR><BR>class base { public: int data; };<BR>class A : public virtual base {public: int mydata; };<BR>class B : public virtual base { };<BR>class C : public virtual A, public virtual B { };<BR><BR>void main() {<BR>&nbsp;&nbsp; C c;<BR>&nbsp;&nbsp; c.data = 1;<BR>&nbsp;&nbsp; A* pa = &amp;c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//向上强制<BR>&nbsp;&nbsp; B* pb = &amp;c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //向上强制<BR>&nbsp;&nbsp; base* pbase = &amp;c;&nbsp;&nbsp;&nbsp;&nbsp; //向上强制<BR>&nbsp;&nbsp; cout&lt;&lt;&amp;c&lt;&lt;endl&lt;&lt;sizeof(c)&lt;&lt;endl;<BR>&nbsp;&nbsp; printf("%d, %d, %d, %d", c.data, pa-&gt;data, pb-&gt;data, pbase-&gt;data);<BR>}<BR><BR>2003-1-16 13:00:48

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -