?? atl under the hood - part 2.mht
字號:
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/script/images/support_icon.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
href=3D"http://www.codeproject.com/store/"><B>MSDN =
Univ. from=20
$1950</B></A></TD></TR>
<TR vAlign=3Dtop>
<TD></TD>
<TD></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
src=3D"http://www.codeproject.com/images/print.gif" =
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/atl/atl_underthehood_2.asp?print=3Dtru=
e"=20
target=3D_print>Print version</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
src=3D"http://www.codeproject.com/images/link.gif" =
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/add_bookmark.asp?t=3D0&=
amp;ct=3D%2Fatl%2Fatl%5Funderthehood%5F2%2Easp&guid=3D%2Fatl%2FATL%5F=
UnderTheHood%5F2%2Easp%2D2%2F18%2F2002">Bookmark=20
this</A></TD></TR></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
src=3D"http://www.codeproject.com/images/mail.gif" =
width=3D16></TD>
<TD class=3DSmallText><A=20
=
href=3D"http://www.codeproject.com/script/recommend/form.asp?guid=3D%2Fat=
l%2FATL%5FUnderTheHood%5F2%2Easp%2D2%2F18%2F2002">Send=20
to a friend</A></TD></TR>
<TR vAlign=3Dtop>
<TD></TD>
<TD></TD></TR>
<TR vAlign=3Dtop>
<TD></TD>
<TD class=3DInfoBarHeader>My Profile</TD></TR>
<TR>
<TD bgColor=3Dblack colSpan=3D2><IMG height=3D1=20
src=3D"http://www.codeproject.com/images/space.gif"=20
width=3D1></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/profile_small.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/modify.asp?ct=3D/atl/at=
l_underthehood_2.asp">My=20
Settings</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/submit_small.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/articles/list_articles.asp?user=
id=3D273403">My=20
Articles</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/bookmarks.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/bookmark_list.asp">My=20
Bookmarks</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/logoff_small.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/logoff.asp?ct=3D/atl/at=
l_underthehood_2.asp">Sign=20
out</A></TD></TR>
<TR>
<TD bgColor=3Dblack colSpan=3D2><IMG height=3D1=20
src=3D"http://www.codeproject.com/images/space.gif"=20
width=3D1></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD> </TD></TR>
<TR>
<TD>
<CENTER>
<SCRIPT language=3Djavascript=20
=
src=3D"http://media.adcentriconline.com/adcentric/tag/618/685/6791">
</SCRIPT>
<NOSCRIPT><A=20
=
href=3D"http://media.adcentriconline.com/adcentric/click/618/685/6791"><I=
MG=20
=
src=3D"http://media.adcentriconline.com/adcentric/data/618/685/6791;image=
"=20
border=3D0></A> =
</NOSCRIPT><BR></CENTER><BR></TD></TR></TBODY></TABLE></TD>
<TD width=3D5 rowSpan=3D2><IMG height=3D1=20
src=3D"http://www.codeproject.com/images/space.gif" width=3D5> =
</TD>
<TD align=3Dright width=3D"100%" bgColor=3Dwhite>
<TABLE width=3D"100%">
<TBODY>
<TR>
<TD class=3DsmallText vAlign=3Dtop noWrap></TD>
<TD noWrap align=3Dright><A name=3D__top></A>
<TABLE>
<TBODY>
<TR>
<TD class=3DsmallText align=3Dright>22 members have =
rated this=20
article. Result:</TD>
<TD>
<TABLE cellSpacing=3D0 cellPadding=3D0 border=3D2>
<TBODY>
<TR>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D17 border=3D0><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/white.gif"=20
width=3D3 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/white.gif"=20
width=3D20 =
border=3D0></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD class=3DsmallText align=3Dright colSpan=3D2><A=20
title=3D"Calculated as rating x Log10(# votes)"=20
=
href=3D"http://www.codeproject.com/script/articles/top_articles.asp?st=3D=
2">Popularity:=20
5.18</A>. Rating: <B>3.86</B> out of=20
5.</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=3Dtop width=3D"100%">
<DIV id=3Dcontentdiv><!-- Article Starts -->
<H2>Introduction</H2>
<P>In this series of tutorials I am going to discuss some of the =
inner=20
workings of ATL and the techniques that ATL uses. This is the =
second=20
article in the series.</P>
<P>Let's explore some more interesting stuff behind the virtual =
function.=20
To make things consistent I am going to take the same number =
sequence and=20
start my discussion with Program 20.=20
<P>Let's take a look at the following Program=20
<H3>Program 20</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
<iostream></SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;
<SPAN class=3Dcpp-keyword>class</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
<SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> fun() {
cout << <SPAN class=3Dcpp-string>"Base::fun"</SPAN> =
<< endl;
}
<SPAN class=3Dcpp-keyword>void</SPAN> show() {
fun();
}
};
<SPAN class=3Dcpp-keyword>class</SPAN> Drive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
<SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> fun() {
cout << <SPAN class=3Dcpp-string>"Drive::fun"</SPAN> =
<< endl;
}
};
<SPAN class=3Dcpp-keyword>int</SPAN> main() {
Drive d;
d.show();
<SPAN class=3Dcpp-keyword>return</SPAN> <SPAN =
class=3Dcpp-literal>0</SPAN>;
}
</PRE>The output of the program is <PRE>Drive::fun</PRE>This program =
clearly shows how the base class's=20
function calls the drive class function if that function is =
virtual. This=20
technique is used in different frameworks like MFC and design =
pattern like=20
Template Design Pattern. Now change program little bit to see its=20
behavior. Now I m going to call virtual function from constructor =
of Base=20
class rather than member function.=20
<H3>Program 21</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
<iostream></SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;
<SPAN class=3Dcpp-keyword>class</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
Base() {
fun();
}
<SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> fun() {
cout << <SPAN class=3Dcpp-string>"Base::fun"</SPAN> =
<< endl;
}
};
<SPAN class=3Dcpp-keyword>class</SPAN> Drive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
<SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> fun() {
cout << <SPAN class=3Dcpp-string>"Drive::fun"</SPAN> =
<< 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>Base::fun
</PRE>This program shows that we can't call a virtual function of a=20
derived class from constructor of a base class. Ok to see =
what is=20
going on under the hood let's print the value of this pointer in =
both=20
constructors. To make things simple remove other functions from =
the=20
classes.=20
<H3>Program 22</H3><PRE><SPAN class=3Dcpp-preprocessor>#include =
<iostream></SPAN>
using <SPAN class=3Dcpp-keyword>namespace</SPAN> std;
<SPAN class=3Dcpp-keyword>class</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
Base() {
cout << <SPAN class=3Dcpp-string>"In Base"</SPAN> << =
endl;
cout << <SPAN class=3Dcpp-string>"This Pointer =3D =
"</SPAN> << (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> << endl;
cout << endl;
}
<SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f() { cout << <SPAN =
class=3Dcpp-string>"Base::f"</SPAN> << endl; }
};
<SPAN class=3Dcpp-keyword>class</SPAN> Drive : <SPAN =
class=3Dcpp-keyword>public</SPAN> Base {
<SPAN class=3Dcpp-keyword>public</SPAN>:
Drive() {
cout << <SPAN class=3Dcpp-string>"In Drive"</SPAN> =
<< endl;
cout << <SPAN class=3Dcpp-string>"This Pointer =3D =
"</SPAN> << (<SPAN class=3Dcpp-keyword>int</SPAN>*)<SPAN =
class=3Dcpp-keyword>this</SPAN> << endl;
cout << endl;
}
<SPAN class=3Dcpp-keyword>virtual</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> f() { cout << <SPAN =
class=3Dcpp-string>"Drive::f"</SPAN> << endl; }
};
<SPAN class=3Dcpp-keyword>int</SPAN> main() {
Drive d;
cout << <SPAN class=3Dcpp-string>"In Main"</SPAN> << =
endl;
cout << (<SPAN class=3Dcpp-keyword>int</SPAN>*)&d << =
endl;
<SPAN class=3Dcpp-keyword>return</SPAN> <SPAN =
class=3Dcpp-literal>0</SPAN>;
}
</PRE>The output of the program is <PRE>In Base
This Pointer =3D 0012FF7C
In Drive
This Pointer =3D 0012FF7C
In Main
0012FF7C
</PRE>This shows that there is only one object in the memory location. =
Now=20
let's print the value at this pointer, i.e. value of vptr and =
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -