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

📄 ch14.htm

📁 一本好的VC学习书,本人就是使用这本书开始学习的vc,希望能对大家有帮助
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On line 17, the static membervariable <TT>HowManyCats</TT> is declared to have private access. Now you cannotaccess this variable from non-member functions, such as <TT>TelepathicFunction</TT>from the previous listing.</P><P>Even though <TT>HowManyCats</TT> is static, it is still within the scope of theclass. Any class function, such as <TT>GetHowMany()</TT>, can access it, just asmember functions can access any member data. However, for a function to call <TT>GetHowMany()</TT>,it must have an object on which to call the function.<BLOCKQUOTE>	<P><HR><B>DO</B> use static member variables to share data among all instances of a class.	<B>DO</B> make static member variables protected or private if you wish to restrict	access to them. <B>DON'T </B>use static member variables to store data for one object.	Static member data is shared among all objects of its class. <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading9"></A><FONT COLOR="#000077">Static Member Functions</FONT></H3><P>Static member functions are like static member variables: they exist not in anobject but in the scope of the class. Thus, they can be called without having anobject of that class, as illustrated in Listing 14.4.</P><P><A NAME="Heading10"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 14.4. Staticmember functions.</B></FONT><PRE><FONT COLOR="#0066FF">1:     //Listing 14.4 static data members2:3:     #include &lt;iostream.h&gt;4:5:     class Cat6:     {7:     public:8:        Cat(int age):itsAge(age){HowManyCats++; }9:        virtual ~Cat() { HowManyCats--; }10:       virtual int GetAge() { return itsAge; }11:       virtual void SetAge(int age) { itsAge = age; }12:       static int GetHowMany() { return HowManyCats; }13:    private:14:       int itsAge;15:       static int HowManyCats;16:    };17:18:    int Cat::HowManyCats = 0;19:20:    void TelepathicFunction();21:22:    int main()23:    {24:       const int MaxCats = 5;25:       Cat *CatHouse[MaxCats]; int i;26:       for (i = 0; i&lt;MaxCats; i++)27:       {28:          CatHouse[i] = new Cat(i);29:          TelepathicFunction();30:       }31:32:       for ( i = 0; i&lt;MaxCats; i++)33:       {34:          delete CatHouse[i];35:          TelepathicFunction();36:       }37:       return 0;38:    }39:40:    void TelepathicFunction()41:    {42:       cout &lt;&lt; &quot;There are &quot; &lt;&lt; Cat::GetHowMany() &lt;&lt; &quot; cats alive!\n&quot;;<TT>43: }</TT></FONT><FONT COLOR="#0066FF">Output: There are 1 cats alive!There are 2 cats alive!There are 3 cats alive!There are 4 cats alive!There are 5 cats alive!There are 4 cats alive!There are 3 cats alive!There are 2 cats alive!There are 1 cats alive!There are 0 cats alive! </FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>The static member variable<TT>HowManyCats</TT> is declared to have private access on line 15 of the <TT>Cat</TT>declaration. The public accessor function, <TT>GetHowMany()</TT>, is declared tobe both public and static on line 12.</P><P>Since <TT>GetHowMany()</TT> is public, it can be accessed by any function, andsince it is static there is no need to have an object of type <TT>Cat</TT> on whichto call it. Thus, on line 42, the function <TT>TelepathicFunction()</TT> is ableto access the public static accessor, even though it has no access to a <TT>Cat</TT>object. Of course, you could have called <TT>GetHowMany()</TT> on the <TT>Cat</TT>objects available in <TT>main()</TT>, just as with any other accessor functions.<BLOCKQUOTE>	<P><HR><FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>Static member functions do not have	a <TT>this</TT> pointer. Therefore, they cannot be declared <TT>const</TT>. Also,	because member data variables are accessed in member functions using the <TT>this</TT>	pointer, static member functions cannot access any non-static member variables! <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading12"></A><FONT COLOR="#000077">Static Member Functions</FONT></H3><P>You can access static member functions by calling them on an object of the classjust as you do any other member function, or you can call them without an objectby fully qualifying the class and object name. Example</P><PRE><FONT COLOR="#0066FF">class Cat{public:static int GetHowMany() { return HowManyCats; }private:static int HowManyCats;};int Cat::HowManyCats = 0;int main(){int howMany;Cat theCat;                       // define a cathowMany = theCat.GetHowMany();   // access through an objecthowMany = Cat::GetHowMany();     // access without an object}</FONT></PRE><H3 ALIGN="CENTER"><A NAME="Heading13"></A><FONT COLOR="#000077">Pointers to Functions</FONT></H3><P>Just as an array name is a constant pointer to the first element of the array,a function name is a constant pointer to the function. It is possible to declarea pointer variable that points to a function, and to invoke the function by usingthat pointer. This can be very useful; it allows you to create programs that decidewhich functions to invoke based on user input.</P><P>The only tricky part about function pointers is understanding the type of theobject being pointed to. A pointer to <TT>int</TT> points to an integer variable,and a pointer to a function must point to a function of the appropriate return typeand signature.</P><P>In the declaration</P><PRE><FONT COLOR="#0066FF">long (* funcPtr) (int);</FONT></PRE><P><TT>funcPtr</TT> is declared to be a pointer (note the <TT>*</TT> in front ofthe name) that points to a function that takes an integer parameter and returns a<TT>long</TT>. The parentheses around <TT>* funcPtr</TT> are necessary because theparentheses around <TT>int</TT> bind more tightly, that is they have higher precedencethan the indirection operator (<TT>*</TT>). Without the first parentheses this woulddeclare a function that takes an integer and returns a pointer to a <TT>long</TT>.(Remember that spaces are meaningless here.)</P><P>Examine these two declarations:</P><PRE><FONT COLOR="#0066FF">long * Function (int);long (* funcPtr) (int);</FONT></PRE><P>The first, <TT>Function</TT> <TT>()</TT>, is a function taking an integer andreturning a pointer to a variable of type <TT>long</TT>. The second, <TT>funcPtr</TT>,is a pointer to a function taking an integer and returning a variable of type <TT>long</TT>.</P><P>The declaration of a function pointer will always include the return type andthe parentheses indicating the type of the parameters, if any. Listing 14.5 illustratesthe declaration and use of function pointers.</P><P><A NAME="Heading14"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 14.5. Pointersto functions.</B></FONT><PRE><FONT COLOR="#0066FF">1:     // Listing 14.5 Using function pointers2:3:     #include &lt;iostream.h&gt;4:5:     void Square (int&amp;,int&amp;);6:     void Cube (int&amp;, int&amp;);7:     void Swap (int&amp;, int &amp;);8:     void GetVals(int&amp;, int&amp;);9:     void PrintVals(int, int);10:    enum BOOL { FALSE, TRUE };11:12:    int main()13:    {14:       void (* pFunc) (int &amp;, int &amp;);15:       BOOL fQuit = FALSE;16:17:       int valOne=1, valTwo=2;18:       int choice;19:       while (fQuit == FALSE)20:       {21:          cout &lt;&lt; &quot;(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: &quot;;22:          cin &gt;&gt; choice;23:          switch (choice)24:          {25:             case 1: pFunc = GetVals; break;26:             case 2: pFunc = Square; break;27:             case 3: pFunc = Cube; break;28:             case 4: pFunc = Swap; break;29:             default : fQuit = TRUE; break;30:          }31:32:          if (fQuit)33:             break;34:35:          PrintVals(valOne, valTwo);36:          pFunc(valOne, valTwo);37:          PrintVals(valOne, valTwo);38:       }39:     return 0;40:    }41:42:    void PrintVals(int x, int y)43:    {44:       cout &lt;&lt; &quot;x: &quot; &lt;&lt; x &lt;&lt; &quot; y: &quot; &lt;&lt; y &lt;&lt; endl;45:    }46:47:    void Square (int &amp; rX, int &amp; rY)48:    {49:       rX *= rX;50:       rY *= rY;51:    }52: 53:    void Cube (int &amp; rX, int &amp; rY)54:    {55:       int tmp;56: 57:       tmp = rX;58:       rX *= rX;59:       rX = rX * tmp;60:61:       tmp = rY;62:       rY *= rY;63:       rY = rY * tmp;64:    }65:66:    void Swap(int &amp; rX, int &amp; rY)67:    {68:       int temp;69:       temp = rX;70:       rX = rY;71:       rY = temp;72:    }73:74:    void GetVals (int &amp; rValOne, int &amp; rValTwo)75:    {76:       cout &lt;&lt; &quot;New value for ValOne: &quot;;77:       cin &gt;&gt; rValOne;78:       cout &lt;&lt; &quot;New value for ValTwo: &quot;;79:       cin &gt;&gt; rValTwo;<TT>80: }</TT></FONT><FONT COLOR="#0066FF">Output: (0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 1x: 1 y: 2New value for ValOne: 2New value for ValTwo: 3x: 2 y: 3(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 3x: 2 y: 3x: 8 y: 27(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 2x: 8 y: 27x: 64 y: 729(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 4x: 64 y: 729x: 729 y: 64(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 0</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On lines 5-8, four functionsare declared, each with the same return type and signature, returning <TT>void</TT>and taking two references to integers.</P><P>On line 14, <TT>pFunc</TT> is declared to be a pointer to a function that returns<TT>void</TT> and takes two integer reference parameters. Any of the previous functionscan be pointed to by <TT>pFunc</TT>. The user is repeatedly offered the choice ofwhich functions to invoke, and <TT>pFunc</TT> is assigned accordingly. On lines 35-36,the current value of the two integers is printed, the currently assigned functionis invoked, and then the values are printed again.<H3 ALIGN="CENTER"><A NAME="Heading16"></A><FONT COLOR="#000077">Pointer to Function</FONT></H3><P>A pointer to function is invoked exactly like the functions it points to, exceptthat the function pointer name is used instead of the function name. Assign a pointerto function to a specific function by assigning to the function name without theparentheses. The function name is a constant pointer to the function itself. Usethe pointer to function just as you would the function name. The pointer to functionmust agree in return value and signature with the function to which you assign it.Example</P><PRE><FONT COLOR="#0066FF">long (*pFuncOne) (int, int);long SomeFunction (int, int);pFuncOne = SomeFunction;pFuncOne(5,7); </FONT></PRE><H4 ALIGN="CENTER"><A NAME="Heading17"></A><FONT COLOR="#000077">Why Use FunctionPointers?</FONT></H4><P>You certainly could write the program in Listing 14.5 without function pointers,but the use of these pointers makes the intent and use of the program explicit: picka function from a list, and then invoke it.</P><P>Listing 14.6 uses the function prototypes and definitions from Listing 14.5, butthe body of the program does not use a function pointer. Examine the differencesbetween these two listings.<BLOCKQUOTE>	<P><HR><FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>To compile this program, place lines	41-80 from Listing 14.5 immediately after line 56. <HR></BLOCKQUOTE><P><A NAME="Heading18"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 14.6. RewritingListing 14.5 without the pointer to function.</B></FONT><PRE><FONT COLOR="#0066FF">1:     // Listing 14.6 Without function pointers2:3:     #include &lt;iostream.h&gt;4:5:     void Square (int&amp;,int&amp;);6:     void Cube (int&amp;, int&amp;);7:     void Swap (int&amp;, int &amp;);8:     void GetVals(int&amp;, int&amp;);9:     void PrintVals(int, int);10:    enum BOOL { FALSE, TRUE };11:12:    int main()13:    {14:       BOOL fQuit = FALSE;15:       int valOne=1, valTwo=2;16:       int choice;17:       while (fQuit == FALSE)18:       {19:          cout &lt;&lt; &quot;(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: &quot;;20:          cin &gt;&gt; choice;21:          switch (choice)22:          {23:             case 1:24:                PrintVals(valOne, valTwo);25:                GetVals(valOne, valTwo);26:                PrintVals(valOne, valTwo);27:                break;28:29:             case 2:30:                PrintVals(valOne, valTwo);

⌨️ 快捷键说明

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