📄 miintro.htm
字号:
<P><A NAME="dingp23"></A><font ID="mhtitle">Conventions and Terminology</font><SCRIPT>create_link(23);</SCRIPT>
</P>
<A NAME="72706"> </A>
<P><A NAME="dingp24"></A>
<A NAME="74722"></A>
Any time I mention inheritance in this book, I mean public inheritance (see <a href="../EC/EI35_FR.HTM#6914" TARGET="_top">Item E35</A>). If I don't mean public inheritance, I'll say so explicitly. When drawing inheritance hierarchies, I depict base-derived relationships by drawing arrows from derived classes to base classes. For example, here is a hierarchy from <a href="./MI31_FR.HTM#34883" TARGET="_top">Item 31</A>:<SCRIPT>create_link(24);</SCRIPT>
</P>
<A NAME="73989"></A><A NAME="73990"></A><A NAME="74752"></A>
<SPAN ID="Image1of1" STYLE="position: absolute; z-index:1; visibility: hidden"><IMG SRC="./IMAGES/GRAPHICS/DIAGRAMS/I_005a1.GIF" BORDER=0></SPAN>
<SPAN ID="Image1of2" STYLE="position: absolute; z-index:1; visibility: hidden"><IMG SRC="./IMAGES/GRAPHICS/DIAGRAMS/I_005a2.GIF" BORDER=0></SPAN>
<SPAN ID="Image1of3" STYLE="position: absolute; z-index:1; visibility: hidden"><IMG SRC="./IMAGES/GRAPHICS/DIAGRAMS/I_005a3.GIF" BORDER=0></SPAN>
<SPAN ID="Image1of4" STYLE="position: absolute; z-index:1; visibility: hidden"><IMG SRC="./IMAGES/GRAPHICS/DIAGRAMS/I_005a4.GIF" BORDER=0></SPAN>
<SPAN ID="Image1of5" STYLE="position: absolute; z-index:1; visibility: hidden"><IMG SRC="./IMAGES/GRAPHICS/DIAGRAMS/I_005a5.GIF" BORDER=0></SPAN>
<SPAN ID="Image1of6" STYLE="position: relative; z-index:1; visibility: hidden"><IMG SRC="./IMAGES/GRAPHICS/DIAGRAMS/I_005a5.GIF" BORDER=0></SPAN>
<A NAME="72673"> </A>
<P><A NAME="dingp25"></A>
This notation is the reverse of the convention I employed in the <A NAME="74617"></A>first (but not the second) edition of <I>Effective C++</I>. I'm now convinced that most C++ practitioners draw inheritance arrows from derived to base classes, and I am happy to follow suit. Within such diagrams, abstract classes (e.g., <CODE>GameObject</CODE>) are shaded and concrete classes (e.g., <CODE>SpaceShip</CODE>) are <NOBR>unshaded.<SCRIPT>create_link(25);</SCRIPT>
</NOBR></P>
<A NAME="72671"> </A>
<P><A NAME="dingp26"></A>
Inheritance gives rise to pointers and references with two different types, a <I>static type</I> and a <I>dynamic type</I>. The static type of a pointer or reference is its <I>declared</I> type. The dynamic type is determined by the type of object it actually <I>refers</I> to. Here are some examples based on the classes <NOBR>above:<SCRIPT>create_link(26);</SCRIPT>
</NOBR></P>
<UL><A NAME="49303"> </A>
<PRE>GameObject *pgo = // static type of pgo is
new SpaceShip; // GameObject*, dynamic
// type is SpaceShip*
</PRE><A NAME="49306"> </A>
<PRE>Asteroid *pa = new Asteroid; // static type of pa is
// Asteroid*. So is its
// dynamic type
</PRE><A NAME="49307"> </A>
<PRE>pgo = pa; // static type of pgo is
// still (and always)
// GameObject*. Its
// dynamic type is now
// Asteroid*
</PRE><A NAME="49316"> </A>
<A NAME="74830"></A><PRE><A NAME="p6"></A>GameObject& rgo = *pa; // static type of rgo is
// GameObject, dynamic
// type is Asteroid
</PRE>
</UL>
<A NAME="49323"></A>
<P><A NAME="dingp27"></A>
These examples also demonstrate a naming convention I like. <CODE>pgo</CODE> is a pointer-to-<CODE>GameObject</CODE>; <CODE>pa</CODE> is a pointer-to-<CODE>Asteroid</CODE>; <CODE>rgo</CODE> is a reference-to-<CODE>GameObject</CODE>. I often concoct pointer and reference names in this <NOBR>fashion.<SCRIPT>create_link(27);</SCRIPT>
</NOBR></P>
<A NAME="63183"></A>
<P><A NAME="dingp28"></A>
Two of my favorite parameter names are <CODE>lhs</CODE> and <CODE>rhs</CODE>, abbreviations for "left-hand side" and "right-hand side," respectively. To understand the rationale behind these names, consider a class for representing rational <NOBR>numbers:<SCRIPT>create_link(28);</SCRIPT>
</NOBR></P>
<UL><A NAME="73147"> </A>
<PRE>class Rational { ... };
</PRE>
</UL>
<A NAME="73148"> </A>
<P><A NAME="dingp29"></A>If I wanted a function to compare pairs of <CODE>Rational</CODE> objects, I'd declare it like <NOBR>this:<SCRIPT>create_link(29);</SCRIPT>
</NOBR></P>
<UL><A NAME="73154"> </A>
<PRE>bool operator==(const Rational& lhs, const Rational& rhs);
</PRE>
</UL>
<A NAME="49216"> </A>
<P><A NAME="dingp30"></A>
That would let me write this kind of <NOBR>code:<SCRIPT>create_link(30);</SCRIPT>
</NOBR></P>
<UL><A NAME="73174"> </A>
<PRE>Rational r1, r2;
</PRE><A NAME="73175"> </A>
<PRE>...
</PRE><A NAME="73176"> </A>
<PRE>if (r1 == r2) ...
</PRE>
</UL>
<A NAME="73177"> </A>
<P><A NAME="dingp31"></A>
Within the call to <CODE>operator==</CODE>, <CODE>r1</CODE> appears on the left-hand side of the "<CODE>==</CODE>" and is bound to <CODE>lhs</CODE>, while <CODE>r2</CODE> appears on the right-hand side of the "<CODE>==</CODE>" and is bound to <CODE>rhs</CODE>.<SCRIPT>create_link(31);</SCRIPT>
</P>
<A NAME="73173"> </A>
<A NAME="72151"></A>
<P><A NAME="dingp32"></A>
Other abbreviations I employ include <I>ctor</I> for "constructor," <I>dtor</I> for "destructor," and <I>RTTI</I> for C++'s support for runtime type identification (of which <CODE>dynamic_cast</CODE> is the most commonly used <NOBR>component).<SCRIPT>create_link(32);</SCRIPT>
</NOBR></P>
<A NAME="73488"> </A>
<P><A NAME="dingp33"></A><A NAME="74776"></A>
When you allocate memory and fail to free it, you have a memory leak. Memory leaks arise in both C and C++, but in C++, memory leaks leak more than just memory. That's because C++ automatically calls constructors when objects are created, and constructors may themselves allocate resources. For example, consider this <NOBR>code:<SCRIPT>create_link(33);</SCRIPT>
</NOBR></P>
<UL><A NAME="73494"> </A>
<PRE>class Widget { ... }; // some class — it doesn't
// matter what it is
</PRE><A NAME="73495"> </A>
<PRE>Widget *pw = new Widget; // dynamically allocate a
// Widget object
</PRE><A NAME="73496"> </A>
<PRE>... // assume pw is never
// deleted
</PRE>
</UL>
<A NAME="73497"> </A>
<P><A NAME="dingp34"></A>
This code leaks memory, because the <CODE>Widget</CODE> pointed to by <CODE>pw</CODE> is never deleted. However, if the <CODE>Widget</CODE> constructor allocates additional re<A NAME="p7"></A>sources that are to be released when the <CODE>Widget</CODE> is destroyed (such as file descriptors, semaphores, window handles, database locks, etc.), those resources are lost just as surely as the memory is. To emphasize that memory leaks in C++ often leak other resources, too, I usually speak of <I>resource leaks</I> in this book rather than memory <NOBR>leaks.<SCRIPT>create_link(34);</SCRIPT>
</NOBR></P>
<A NAME="73457"> </A>
<P><A NAME="dingp35"></A>
You won't see many inline functions in this book. That's not because I dislike inlining. Far from it, I believe that inline functions are an important feature of C++. However, the criteria for determining whether a function should be inlined can be complex, subtle, and platform-dependent (see <a href="../EC/EI33_FR.HTM#6729" TARGET="_top">Item E33</A>). As a result, I avoid inlining unless there is a point about inlining I wish to make. When you see a non-inline function in <I>More Effective C++</I>, that doesn't mean I think it would be a bad idea to declare the function <CODE>inline</CODE>, it just means the decision to inline that function is independent of the material I'm examining at that point in the <NOBR>book.<SCRIPT>create_link(35);</SCRIPT>
</NOBR></P>
<A NAME="73442"> </A>
<P><A NAME="dingp36"></A><A NAME="74000"></A>
A few C++ features have been <I>deprecated</I> by the <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=committee" onMouseOver="self.status='ISO/ANSI Standardization Committee Home Page'; return true" onMouseOut="self.status=self.defaultStatus" target="_top">standardization</NOBR> committee</A>. Such features are slated for eventual removal from the language, because newer features have been added that do what the deprecated features do, but do it better. In this book, I identify deprecated constructs and explain what features replace them. You should try to avoid deprecated features where you can, but there's no reason to be overly concerned about their use. In the interest of preserving backward compatibility for their customers, compiler vendors are likely to support deprecated features for many <NOBR>years.<SCRIPT>create_link(36);</SCRIPT>
</NOBR></P>
<A NAME="74035"> </A>
<P><A NAME="dingp37"></A>
A <I>client</I> is somebody (a programmer) or something (a class or function, typically) that uses the code you write. For example, if you write a <CODE>Date</CODE> class (for representing birthdays, deadlines, when the Second Coming occurs, etc.), anybody using that class is your client. Furthermore, any sections of code that use the <CODE>Date</CODE> class are your clients as well. Clients are important. In fact, clients are the name of the game! If nobody uses the software you write, why write it? You will find I worry a lot about making things easier for clients, often at the expense of making things more difficult for you, because good software is "clientcentric" — it revolves around clients. If this strikes you as unreasonably philanthropic, view it instead through a lens of self-interest. Do you ever use the classes or functions you write? If so, you're your own client, so making things easier for clients in general also makes them easier for <NOBR>you.<SCRIPT>create_link(37);</SCRIPT>
</NOBR></P>
<A NAME="11370"> </A>
<P><A NAME="dingp38"></A><A NAME="74758"></A>
When discussing class or function templates and the classes or functions generated from them, I reserve the right to be sloppy about the difference between the templates and their instantiations. For example, if <CODE>Array</CODE> is a class template taking a type parameter <CODE>T</CODE>, I may refer to a particular instantiation of the template as an <CODE>Array</CODE>, even though <A NAME="p8"></A><CODE>Array<T></CODE> is really the name of the class. Similarly, if <CODE>swap</CODE> is a function template taking a type parameter <CODE>T</CODE>, I may refer to an instantiation as <CODE>swap</CODE> instead of <CODE>swap<T></CODE>. In cases where this kind of shorthand might be unclear, I include template parameters when referring to template <NOBR>instantiations.<SCRIPT>create_link(38);</SCRIPT>
</NOBR></p>
<P><A NAME="dingp39"></A><font ID="mhtitle">Reporting Bugs, Making Suggestions, Getting Book Updates</font><SCRIPT>create_link(39);</SCRIPT>
</P>
<p><A NAME="dingp40"></A><A NAME="74186"> </A>
I have tried to make this book as accurate, readable, and useful as possible, but I know there is room for improvement. If you find an error of any kind — technical, grammatical, typographical, <I>whatever</I> — please tell me about it. I will try to correct the mistake in future printings of the book, and if you are the first person to report it, I will gladly add your name to the book's acknowledgments. If you have other suggestions for improvement, I welcome those, <NOBR>too.<SCRIPT>create_link(40);</SCRIPT>
</NOBR></P>
<A NAME="74187"> </A>
<P><A NAME="dingp41"></A>
I continue to collect guidelines for effective programming in C++. If you have ideas for new guidelines, I'd be delighted if you'd share them with me. Send your guidelines, your comments, your criticisms, and your bug reports <NOBR>to:<SCRIPT>create_link(41);</SCRIPT>
</NOBR></P>
<A NAME="dingp42"></A><Dl><A NAME="74189"> </A><A NAME="74845"></A>
<DD>Scott Meyers
<DD>c/o Editor-in-Chief, Corporate and Professional Publishing
<DD>Addison-Wesley Publishing Company
<DD>1 Jacob Way
<DD>Reading, MA 01867
<DD>U. S. A.<SCRIPT>create_link(42);</SCRIPT>
</DL>
<A NAME="74190"> </A>
<P><A NAME="dingp43"></A>
Alternatively, you may send electronic mail to <A HREF="mailto:mec++@awl.com"><CODE>mec++@awl.com</CODE></A>.<SCRIPT>create_link(43);</SCRIPT>
</P>
<A NAME="74191"> </A>
<P><A NAME="dingp44"></A>
I maintain a list of changes to this book since its first printing, including bug-fixes, clarifications, and technical updates. This list, along with other book-related information, is available from the <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=bookm" onMouseOver="self.status='Addison Wesley Web Site for this product'; return true" onMouseOut="self.status=self.defaultStatus" target="_top">Web</NOBR> site for this book</A>. It is also available via anonymous FTP from <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=ftpawl" onMouseOver="self.status='Addison Wesley Longman Anonymous FTP'; return true" onMouseOut="self.status=self.defaultStatus" target="_top"><CODE>ftp.awl.com</CODE></A></NOBR> in the directory <CODE>cp/mec++</CODE>. If you would like a copy of the list of changes to this book, but you lack access to the Internet, please send a request to one of the addresses above, and I will see that the list is sent to <NOBR>you.<SCRIPT>create_link(44);</SCRIPT>
</NOBR></P>
<A NAME="73362"> </A>
<P><A NAME="dingp45"></A>Enough preliminaries. On with the <NOBR>show!<SCRIPT>create_link(45);</SCRIPT>
</NOBR></p>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./MIACK_FR.HTM" TARGET="_top">Acknowledgments</A> <BR> Continue to <A HREF="./MBASICFR.HTM" TARGET="_top">Basics</A></FONT></DIV>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -