虚函数

来源:互联网 发布:章亦春 nginx 编辑:程序博客网 时间:2024/05/17 01:42
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//首先让我们来了解类对象的构造顺序。</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> A{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    A(){ <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"A"</span> << endl; }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfA() = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> B {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    B(){ <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"B"</span> << endl; }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> C :<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> A , <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> B{    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//关于构造对象顺序:</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第一步先构造虚基类,例如此处的虚继承。</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第二步构造一般继承类,此处从左往右顺序执行。</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第三部构造成员变量,记住这里的成员变量的构造是顺序执行的。</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第四构造自身的构造函数。</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    C()    { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C"</span> << endl; }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfA()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello word!!"</span> << endl;    }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span>:};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(){    C c;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

这里写图片描述

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> (*Pfun)();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Base{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Printf()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Base::Printf()"</span> << endl;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfBae()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Base::PrintfBase"</span> << endl;    }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Son1:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Base{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Printf()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Son1::Printf()"</span> << endl;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfSon1()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Son1::PrintfSon1()"</span> << endl;    }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Son2 : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Son1{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Printf()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Son2::Printf()"</span> << endl;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> hello()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span> << endl;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfSon2()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Son2::Printf()"</span> << endl;    }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(){    Son2 s2;    Base &b = s2;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//b.Printf();</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此处可以得出这三个类维护了一个共同的虚表,但是我们还无法知道他们的</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//具体位置以及各个类里面非虚函数的存储关系,所以我们接下来验证。</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Pfun fun = (Pfun)*((int *)(&(int*)&b)+1);</span>    Pfun fun = (Pfun)*((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)*(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(&b) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这种做法基本没有人解释,所以我在后面用图解释了。</span>    fun();    fun = (Pfun)*((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)*(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(&b) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);    fun();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//--------------------------------------------------------</span>    fun = (Pfun)*((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)*(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(&s2) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);    fun();    fun = (Pfun)*((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)*(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(&b) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);    fun();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//打印结果与上面一样,可以得出这份虚表是所有继承该拥有虚表基类的成员类所共享的。</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//每个对象的产生必定有两个数据,一个vptr指向虚表的指针,还有其自身的成员</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//变量。</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//总结1:前提是基类是有虚表的,单一继承,所有的成员类与基类共同维护同一个虚表,各自有</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//一个vptr指向这个虚表,子类如果会对虚表进行替换修改,具体会根据子类是否重载了基类的</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//虚函数来确定,我们成为覆盖。多继承下面讨论,其实本质是一样的,关键问题是,多继承中</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//子类中到底有几份虚vptr指针。</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li></ul>

这里写图片描述

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include<iostream></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> A{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Printf()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"A::Printf()"</span> << endl;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfA()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"A::PrintfA()"</span> << endl;    }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> B{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> PrintfB()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"B::Printf()"</span> << endl;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">virtual</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Printf()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"B::Printf()"</span> << endl;    }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> C : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> A, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> B{<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span>:    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Printf()    {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C::Printf()"</span> << endl;    }};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(){    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>(*PFun)();    C c;    PFun fun = (PFun)*((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)*(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(&c)+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第一个虚表指针vptr。</span>    fun();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此处覆盖了,调用的是C中的Printf();</span>    fun = (PFun)* ((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)*(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *)(&c) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第二个虚表指针vptr。</span>    fun();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此处还有一个亮点,就是为什么(int *)(int *)两次,这下你应该明白了吧,因为可能</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//有多个虚指针,编译器做的很好了,如果不这样做编译会报错。</span>    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(c) << endl;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//终极测试结果8。</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//总结2:多继承中每一个基类都维护一张自己的虚表,而子类中每继承一个虚基类就会有存在一个</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//指向该基类虚表的指针,以上代码测试结果是C对象中有两个vptr指针,一个指向A基类的虚表,一</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//个指向B基类的虚表。</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li></ul>

这里写图片描述

0 0
原创粉丝点击