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

📄 chapter11.html

📁 think like a computer scientist
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<TT>hour</TT>, <TT>minute</TT> and <TT>second</TT>, the compiler knows we are referring to the instance variables of the new object.</P><P>To invoke the constructor, you use syntax that is a cross between a variabledeclaration and a function call:</P><PRE>  Time time (seconds);</PRE><P>This statement declares that the variable <TT>time</TT> has type <TT>Time</TT>, and it invokes the constructor we just wrote, passing the value of <TT>seconds</TT> as an argument. The system allocates space for the new object and the constructor initializes its instance variables. The result is assigned to the variable <TT>time</TT>.</P><BR><BR><H3>11.8 Initialize or construct?</H3><P>Earlier we declared and initialized some <TT>Time</TT> structures using squiggly-braces:</P><PRE>  Time currentTime = { 9, 14, 30.0 };  Time breadTime = { 3, 35, 0.0 };</PRE><P>Now, using constructors, we have a different way to declare and initialize:</P><PRE>  Time time (seconds);</PRE><P>These two functions represent different programming styles, and different points in the history of C++. Maybe for that reason, the C++ compiler requires that you use one or the other, and not both in the same program.</P><P>If you define a constructor for a structure, then you have to use the constructor to initialize all new structures of that type. The alternate syntaxusing squiggly-braces is no longer allowed.</P><P>Fortunately, it is legal to overload constructors in the same way we overloaded functions. In other words, there can be more than one constructor with the same ``name,'' as long as they take different parameters. Then, when we initialize a new object the compiler will try to find a constructor that takes the appropriate parameters.</P><P>For example, it is common to have a constructor that takes one parameter foreach instance variable, and that assigns the values of the parameters to the instance variables:</P><PRE>Time::Time (int h, int m, double s){  hour = h;  minute = m;  second = s;}</PRE><P>To invoke this constructor, we use the same funny syntax as before, except that the arguments have to be two integers and a <TT>double</TT>:</P><PRE>  Time currentTime (9, 14, 30.0);</PRE><BR><BR><H3>11.9 One last example</H3><P>The final example we'll look at is <TT>addTime</TT>:</P><PRE>Time addTime2 (const Time& t1, const Time& t2) {  double seconds = convertToSeconds (t1) + convertToSeconds (t2);  return makeTime (seconds);}</PRE><P>We have to make several changes to this function, including:</P><OL>  <LI>Change the name from <TT>addTime</TT> to <TT>Time::add</TT>.</LI><BR><BR>  <LI>Replace the first parameter with an implicit parameter, which should be   declared <TT>const</TT>.</LI><BR><BR>  <LI>Replace the use of <TT>makeTime</TT> with a constructor invocation.</LI></OL><P>Here's the result:</P><PRE>Time Time::add (const Time& t2) const {  double seconds = convertToSeconds () + t2.convertToSeconds ();  Time time (seconds);  return time;}</PRE><P>The first time we invoke <TT>convertToSeconds</TT>, there is no apparent object!  Inside a member function, the compiler assumes that we want to invoke the function on the current object. Thus, the first invocation acts on <TT>this</TT>; the second invocation acts on <TT>t2</TT>.</P><P>The next line of the function invokes the constructor that takes a single <TT>double</TT> as a parameter; the last line returns the resulting object.</P><BR><BR><H3>11.10 Header files</H3><P>It might seem like a nuisance to declare functions inside the structure definition and then define the functions later. Any time you change the interface to a function, you have to change it in two places, even if it is a small change like declaring one of the parameters <TT>const</TT>.</P><P>There is a reason for the hassle, though, which is that it is now possible to separate the structure definition and the functions into two files: the <B>header file</B>, which contains the structure definition, and the implementation file, which contains the functions.</P><P>Header files usually have the same name as the implementation file, but withthe suffix <TT>.h</TT> instead of <TT>.cpp</TT>. For the example we have been looking at, the header file is called <TT>Time.h</TT>, and it contains the following:</P><PRE>struct Time {  // instance variables  int hour, minute;  double second;  // constructors  Time (int hour, int min, double secs);  Time (double secs);  // modifiers  void increment (double secs);  // functions  void print () const;  bool after (const Time& time2) const;  Time add (const Time& t2) const;  double convertToSeconds () const;};</PRE><P>Notice that in the structure definition I don't really have to include the prefix <TT>Time::</TT> at the beginning of every function name. The compiler knows that we are declaring functions that are members of the <TT>Time</TT> structure.</P><P><TT>Time.cpp</TT> contains the definitions of the member functions (I have elided the function bodies to save space):</P><PRE>#include <iostream.h>#include "Time.h"Time::Time (int h, int m, double s)  ...Time::Time (double secs) ...void Time::increment (double secs) ...void Time::print () const ...bool Time::after (const Time& time2) const ...Time Time::add (const Time& t2) const ...double Time::convertToSeconds () const ...</PRE><P>In this case the definitions in <TT>Time.cpp</TT> appear in the same order as the declarations in <TT>Time.h</TT>, although it is not necessary.</P><P>On the other hand, it is necessary to include the header file using an <TT>include</TT> statement.  That way, while the compiler is reading the function definitions, it knows enough about the structure to check the code andcatch errors.</P> <P>Finally, <TT>main.cpp</TT> contains the function <TT>main</TT> along with any functions we want that are not members of the <TT>Time</TT> structure (in this case there are none):</P><PRE>#include <iostream.h>#include "Time.h"void main (){  Time currentTime (9, 14, 30.0);  currentTime.increment (500.0);  currentTime.print ();  Time breadTime (3, 35, 0.0);  Time doneTime = currentTime.add (breadTime);  doneTime.print ();  if (doneTime.after (currentTime)) {    cout << "The bread will be done after it starts." << endl;  }}</PRE><P>Again, <TT>main.cpp</TT> has to include the header file.</P><P>It may not be obvious why it is useful to break such a small program into three pieces. In fact, most of the advantages come when we are working with larger programs:</P><DL>  <DT>Reuse:</DT><DD> Once you have written a structure like <TT>Time</TT>, you   might find it useful in more than one program. By separating the definition   of <TT>Time</TT> from <TT>main.cpp</TT>, you make is easy to include the   <TT>Time</TT> structure in another program.</DD>  <DT>Managing interactions:</DT><DD> As systems become large, the number of   interactions between components grows and quickly becomes unmanageable. It is  often useful to minimize these interactions by separating modules like   <TT>Time.cpp</TT> from the programs that use them.</DD>  <DT>Separate compilation:</DT><DD> Separate files can be compiled separately   and then linked into a single program later. The details of how to do this   depend on your programming environment. As the program gets large, separate   compilation can save a lot of time, since you usually need to compile only a   few files at a time.</DD></DL><P>For small programs like the ones in this book, there is no great advantage to splitting up programs. But it is good for you to know about this feature, especially since it explains one of the statements that appeared in the first program we wrote:</P><PRE>#include &lt;iostream.h&gt;</PRE><P><TT>iostream.h</TT> is the header file that contains declarations for <TT>cin</TT> and <TT>cout</TT> and the functions that operate on them. When youcompile your program, you need the information in that header file.</P><P>The implementations of those functions are stored in a library, sometimes called the ``Standard Library'' that gets linked to your program automatically.The nice thing is that you don't have to recompile the library every time you compile a program. For the most part the library doesn't change, so there is noreason to recompile it.</P><BR><BR><H3>11.11 Glossary</H3><DL>  <DT>member function:</DT><DD> A function that operates on an object that is   passed as an implicit parameter named <TT>this</TT>.</DD>  <DT>nonmember function:</DT><DD> A function that is not a member of any   structure definition. Also called a ``free-standing'' function.</DD>  <DT>invoke:</DT><DD> To call a function ``on'' an object, in order to pass   the object as an implicit parameter.</DD>  <DT>current object:</DT><DD> The object on which a member function is   invoked. Inside the member function, we can refer to the current object   implicitly, or by using the keyword <TT>this</TT>.</DD>  <DT>this:</DT><DD> A keyword that refers to the current object. <TT>this</TT>  is a pointer, which makes it difficult to use, since we do not cover pointers  in this book.</DD>  <DT>interface:</DT><DD> A description of how a function is used, including   the number and types of the parameters and the type of the return value.</DD>  <DT>function declaration:</DT><DD> A statement that declares the interface to  a function without providing the body. Declarations of member functions   appear inside structure definitions even if the definitions appear outside.  </DD>  <DT>implementation:</DT><DD> The body of a function, or the details of how a   function works.</DD>  <DT>constructor:</DT><DD> A special function that initializes the instance   variables of a newly-created object.</DD></DL><BR><DIV CLASS=navigation><HR>  <TABLE ALIGN=center WIDTH="100%" CELLPADDING=0 CELLSPACING=2>  <TR>    <TD><A HREF="chapter12.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter12.html">      <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="next"       SRC="images/next.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/next.gif"></A>    </TD>    <TD><A HREF="index.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/index.html">      <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="up"       SRC="images/up.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/up.gif"></A>    </TD>    <TD><A HREF="chapter10.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter10.html">      <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="previous"      SRC="images/previous.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/previous.gif"></A>    </TD>    <TD ALIGN=center BGCOLOR="#99CCFF" WIDTH="100%">      <B CLASS=title>How to Think Like a Computer Scientist: Chapter 11</B>    </TD>    <TD><A HREF="index.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/index.html">      <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="contents"      SRC="images/contents.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/contents.gif"></A>    </TD>    <TD>      <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT=""      SRC="images/blank.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/blank.gif">    </TD>    <TD>      <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT=""      SRC="images/blank.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/blank.gif">    </TD>  </TR>  </TABLE>  <B CLASS=navlabel>Next:</B>  <SPAN CLASS=sectref><A HREF="chapter12.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter12.html">Chapter 12</A></SPAN>  <B CLASS=navlabel>Up:</B>  <SPAN CLASS=sectref><A HREF="index.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/index.html">Index</A></SPAN>  <B CLASS=navlabel>Previous:</B>  <SPAN CLASS=sectref><A HREF="chapter10.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter10.html">Chapter 10</A></SPAN>  <HR></DIV></BODY></HTML>

⌨️ 快捷键说明

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