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

📄 atl under the hood - part 2.mht

📁 大家知道wtl是window UI库
💻 MHT
📖 第 1 页 / 共 5 页
字号:
address of=20
      VTable.=20
      <H3>Program 23</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
&lt;iostream&gt;</SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;

<SPAN class=3Dcpp-keyword>class</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    Base() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In Base"</SPAN> &lt;&lt; =
endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"Base::f1"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>class</SPAN> Drive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    Drive() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In Drive"</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"Drive::f2"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>int</SPAN> main() {
    Drive d;
    <SPAN class=3Dcpp-keyword>return</SPAN> <SPAN =
class=3Dcpp-literal>0</SPAN>;
}
</PRE>The output of this program is <PRE>In Base
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C08C
Value at Vtable =3D 004010F0

In Drive
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C07C
Value at Vtable =3D <SPAN class=3Dcpp-literal>00401217</SPAN>
</PRE>This program shows the different vtable address in Base class and=20
      Drive class. To get more better understanding lets make =
inheritance deeper=20
      and add one more class <CODE>MostDrive</CODE> inherited from Drive =
and=20
      make an object of it.=20
      <H3>Program 24</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
&lt;iostream&gt;</SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;

<SPAN class=3Dcpp-keyword>class</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    Base() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In Base"</SPAN> &lt;&lt; =
endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"Base::f1"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>class</SPAN> Drive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    Drive() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In Drive"</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"Drive::f2"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>class</SPAN> MostDrive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Drive {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    MostDrive() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In MostDrive"</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"MostDrive::f2"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>int</SPAN> main() {
    MostDrive d;
    <SPAN class=3Dcpp-keyword>return</SPAN> <SPAN =
class=3Dcpp-literal>0</SPAN>;
}
</PRE>The output of this program is <PRE>In Base
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C0A0
Value at Vtable =3D 004010F5

In Drive
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C090
Value at Vtable =3D <SPAN class=3Dcpp-literal>00401221</SPAN>

In MostDrive
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C080
Value at Vtable =3D <SPAN class=3Dcpp-literal>00401186</SPAN>
</PRE>This program shows that virtual pointer in initialized in the=20
      constructor of each class. Therefore the address of Vtable is =
different in=20
      each class constructor and main use the vtable of most drive class =
in=20
      inheritance chain whose object is created.=20
      <P>Now see what each class constructor place in vtable. To do this =
take=20
      pointer to function and store value of first entry of vtable in =
that=20
      function pointer and try to execute it.=20
      <H3>Program 25</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
&lt;iostream&gt;</SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;

<SPAN class=3Dcpp-keyword>typedef</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN>(*Fun)();

<SPAN class=3Dcpp-keyword>class</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    Base() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In Base"</SPAN> &lt;&lt; =
endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;

        Fun pFun =3D (Fun)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN>;
        pFun();
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"Base::f1"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>class</SPAN> Drive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    Drive() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In Drive"</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
       =20
        Fun pFun =3D (Fun)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN>;
        pFun();
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"Drive::f1"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>class</SPAN> MostDrive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Drive {
<SPAN class=3Dcpp-keyword>public</SPAN>:
    MostDrive() {
        cout &lt;&lt; <SPAN class=3Dcpp-string>"In MostDrive"</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Virtual Pointer =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> &lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Address of Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
        cout &lt;&lt; <SPAN class=3Dcpp-string>"Value at Vtable =3D =
"</SPAN> &lt;&lt; (<SPAN class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN> =
&lt;&lt; endl;
       =20
        Fun pFun =3D (Fun)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)*(<SPAN =
class=3Dcpp-keyword>int</SPAN>*)<SPAN class=3Dcpp-keyword>this</SPAN>;
        pFun();
        cout &lt;&lt; endl;
    }
    <SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f1() { cout &lt;&lt; <SPAN =
class=3Dcpp-string>"MostDrive::f1"</SPAN> &lt;&lt; endl; }
};

<SPAN class=3Dcpp-keyword>int</SPAN> main() {
    MostDrive d;
    <SPAN class=3Dcpp-keyword>return</SPAN> <SPAN =
class=3Dcpp-literal>0</SPAN>;
}
</PRE>The output of this program is <PRE>In Base
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C098
Value at Vtable =3D 004010F5
Base::f1

In Drive
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C088
Value at Vtable =3D <SPAN class=3Dcpp-literal>00401221</SPAN>
Drive::f1

In MostDrive
Virtual Pointer =3D 0012FF7C
Address of Vtable =3D 0046C078
Value at Vtable =3D <SPAN class=3Dcpp-literal>00401186</SPAN>
MostDrive::f1
</PRE>This program shows that constructor of each class fills the vtable =

      entries with their own virtual function. So <CODE>Base</CODE> =
class fills=20
      the vtable with the address of the <CODE>Base</CODE>'s virtual =
functions=20
      and when <CODE>Drive</CODE> class's constructor executes it will =
create=20
      another vtable and store the virtual functions address.=20
      <P>Now see the situation when there is more than one virtual =
function in=20
      the base class and drive class override not all of these.=20
      <H3>Program 26</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
&lt;iostream&gt;</SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;

⌨️ 快捷键说明

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