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

📄 ch15.htm

📁 一本好的VC学习书,本人就是使用这本书开始学习的vc,希望能对大家有帮助
💻 HTM
📖 第 1 页 / 共 5 页
字号:
69:          USHORT itsEngineNumber;70:       };71:     72:       AirPlanePart::AirPlanePart73:           (USHORT EngineNumber, ULONG PartNumber):74:          itsEngineNumber(EngineNumber),75:          Part(PartNumber)76:       {}77:     78:     // **************** Part Node ************79:     class PartNode80:     {81:     public:82:        friend class PartsList;83:        PartNode (Part*);84:        ~PartNode();85:        void SetNext(PartNode * node) 86:            { itsNext = node; }87:        PartNode * GetNext() const;88:        Part * GetPart() const;89:     private:90:        Part *itsPart;91:        PartNode * itsNext;92:     };93:    94:       95:          PartNode::PartNode(Part* pPart):96:          itsPart(pPart),97:          itsNext(0)98:          {}99:       100:          PartNode::~PartNode()101:          {102:              delete itsPart;103:              itsPart = 0;104:              delete itsNext;105:              itsNext = 0;106:           }107:        108:           // Returns NULL if no next PartNode109:           PartNode * PartNode::GetNext() const110:           {111:                 return itsNext;112:           }113:        114:           Part * PartNode::GetPart() const115:           {116:              if (itsPart)117:                 return itsPart;118:              else119:                 return NULL; //error120:           }121:        122:    123:     // **************** Part List ************124:     class PartsList125:     {126:     public:127:        PartsList();128:        ~PartsList();129:        // needs copy constructor and operator equals!130:        void     Iterate(void (Part::*f)()const) const;131:        Part*    Find(ULONG &amp; position, ULONG PartNumber) const;132:        Part*    GetFirst() const;133:        void       Insert(Part *);134:        Part*    operator[](ULONG) const;135:        ULONG    GetCount() const { return itsCount; }136:        static    PartsList&amp; GetGlobalPartsList() 137:                { 138:                    return  GlobalPartsList;139:                }140:     private:141:        PartNode * pHead;142:        ULONG itsCount;143:        static PartsList GlobalPartsList;144:     };145:    146:     PartsList PartsList::GlobalPartsList;147:    148:     // Implementations for Lists...149:    150:     PartsList::PartsList():151:        pHead(0),152:        itsCount(0)153:        {}154:    155:     PartsList::~PartsList()156:     {157:        delete pHead;158:     }159:    160:     Part*   PartsList::GetFirst() const161:     {162:        if (pHead)163:           return pHead-&gt;itsPart;164:        else165:           return NULL;  // error catch here166:     }167:    168:     Part * PartsList::operator[](ULONG offSet) const169:     {170:        PartNode* pNode = pHead;171:    172:        if (!pHead)173:           return NULL; // error catch here174:    175:        if (offSet &gt; itsCount)176:           return NULL; // error177:    178:        for (ULONG i=0;i&lt;offSet; i++)179:           pNode = pNode-&gt;itsNext;180:    181:       return   pNode-&gt;itsPart;182:     }183:    184:    Part* PartsList::Find(ULONG &amp; position, ULONG PartNumber) const185:     {186:        PartNode * pNode = 0;187:        for (pNode = pHead, position = 0;188:              pNode!=NULL;189:              pNode = pNode-&gt;itsNext, position++)190:        {191:           if (pNode-&gt;itsPart-&gt;GetPartNumber() == PartNumber)192:              break;193:        }194:        if (pNode == NULL)195:           return NULL;196:        else197:           return pNode-&gt;itsPart;198:     }199:    200:     void PartsList::Iterate(void (Part::*func)()const) const201:     {202:        if (!pHead)203:           return;204:        PartNode* pNode = pHead;205:        do206:           (pNode-&gt;itsPart-&gt;*func)();207:        while (pNode = pNode-&gt;itsNext);208:     }209:    210:     void PartsList::Insert(Part* pPart)211:     {212:        PartNode * pNode = new PartNode(pPart);213:        PartNode * pCurrent = pHead;214:        PartNode * pNext = 0;215:    216:        ULONG New =  pPart-&gt;GetPartNumber();217:        ULONG Next = 0;218:        itsCount++;219:    220:        if (!pHead)221:        {222:           pHead = pNode;223:           return;224:        }225:    226:        // if this one is smaller than head227:        // this one is the new head228:        if (pHead-&gt;itsPart-&gt;GetPartNumber() &gt; New)229:        {230:           pNode-&gt;itsNext = pHead;231:           pHead = pNode;232:           return;233:        }234:    235:        for (;;)236:        {237:           // if there is no next, append this new one238:           if (!pCurrent-&gt;itsNext)239:           {240:              pCurrent-&gt;itsNext = pNode;241:              return;242:           }243: 244:           // if this goes after this one and before the next245:           // then insert it here, otherwise get the next246:           pNext = pCurrent-&gt;itsNext;247:           Next = pNext-&gt;itsPart-&gt;GetPartNumber();248:           if (Next &gt; New)249:           {250:              pCurrent-&gt;itsNext = pNode;251:              pNode-&gt;itsNext = pNext;252:              return;253:           }254:           pCurrent = pNext;255:        }256:     }257:    258:     class PartsCatalog : private PartsList259:     {260:     public:261:        void Insert(Part *);262:        ULONG Exists(ULONG PartNumber);263:        Part * Get(int PartNumber);264:        operator+(const PartsCatalog &amp;);265:        void ShowAll() { Iterate(Part::Display); }266:     private:267:     };268:    269:     void PartsCatalog::Insert(Part * newPart)270:     {271:        ULONG partNumber =  newPart-&gt;GetPartNumber();272:        ULONG offset;273:    274:        if (!Find(offset, partNumber))275:           PartsList::Insert(newPart);276:        else277:        {278:           cout &lt;&lt; partNumber &lt;&lt; &quot; was the &quot;;279:           switch (offset)280:           {281:              case 0:  cout &lt;&lt; &quot;first &quot;; break;282:              case 1:  cout &lt;&lt; &quot;second &quot;; break;283:              case 2:  cout &lt;&lt; &quot;third &quot;; break;284:              default: cout &lt;&lt; offset+1 &lt;&lt; &quot;th &quot;;285:           }286:           cout &lt;&lt; &quot;entry. Rejected!\n&quot;;287:        }288:     }289:    290:     ULONG PartsCatalog::Exists(ULONG PartNumber)291:     {292:        ULONG offset;293:        Find(offset,PartNumber);294:        return offset;295:     }296:    297:     Part * PartsCatalog::Get(int PartNumber)298:     {299:        ULONG offset;300:        return (Find(offset, PartNumber));301:    302:     }303:    304:     int main()305:     {306:        PartsCatalog pc;307:        Part * pPart = 0;308:        ULONG PartNumber;309:        USHORT value;310:        ULONG choice;311:    312:        while (1)313:        {314:           cout &lt;&lt; &quot;(0)Quit (1)Car (2)Plane: &quot;;315:           cin &gt;&gt; choice;316:    317:           if (!choice)318:              break;319:    320:           cout &lt;&lt; &quot;New PartNumber?: &quot;;321:           cin &gt;&gt;  PartNumber;322:    323:           if (choice == 1)324:           {325:              cout &lt;&lt; &quot;Model Year?: &quot;;326:              cin &gt;&gt; value;327:              pPart = new CarPart(value,PartNumber);328:           }329:           else330:           {331:              cout &lt;&lt; &quot;Engine Number?: &quot;;332:              cin &gt;&gt; value;333:              pPart = new AirPlanePart(value,PartNumber);334:           }335:           pc.Insert(pPart);336:        }337:        pc.ShowAll();338:       return 0;<TT>339: }</TT></FONT><FONT COLOR="#0066FF">Output: (0)Quit (1)Car (2)Plane:  1New PartNumber?: 1234Model Year?: 94(0)Quit (1)Car (2)Plane:  1New PartNumber?: 4434Model Year?: 93(0)Quit (1)Car (2)Plane:  1New PartNumber?: 1234Model Year?: 941234 was the first entry. Rejected!(0)Quit (1)Car (2)Plane:  1New PartNumber?: 2345Model Year?: 93(0)Quit (1)Car (2)Plane:  0Part Number: 1234Model Year: 94Part Number: 2345Model Year: 93Part Number: 4434Model Year: 93</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On line 82, the class <TT>PartsList</TT>is declared to be a friend to the <TT>PartNode</TT> class. Because <TT>PartsList</TT>has not yet been declared, the compiler would complain that this type is not known.</P><P>This listing places the friend declaration in the public section, but this isnot required; it can be put anywhere in the class declaration without changing themeaning of the statement. Because of this statement, all the private member dataand functions are available to any member function of class <TT>PartsList</TT>.</P><P>On line 160, the implementation of the member function <TT>GetFirst()</TT> reflectsthis change. Rather than returning <TT>pHead-&gt;GetPart</TT>, this function cannow return the otherwise private member data by writing <TT>pHead-&gt;itsPart</TT>.Similarly, the <TT>Insert()</TT> function can now write <TT>pNode-&gt;itsNext = pHead</TT>,rather than writing <TT>pNode-&gt;SetNext(pHead)</TT>.</P><P>Admittedly these are trivial changes, and there is not a good enough reason tomake <TT>PartsList</TT> a friend of <TT>PartNode</TT>, but they do serve to illustratehow the keyword <TT>friend</TT> works.</P><P>Declarations of friend classes should be used with extreme caution. If two classesare inextricably entwined, and one must frequently access data in the other, theremay be good reason to use this declaration. But use it sparingly; it is often justas easy to use the public accessor methods, and doing so allows you to change oneclass without having to recompile the other.<BLOCKQUOTE>	<P><HR><FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>You will often hear novice C++ programmers	complain that friend declarations &quot;undermine&quot; the encapsulation so important	to object-oriented programming. This is, frankly, errant nonsense. The friend declaration	makes the declared friend part of the class interface, and is no more an undermining	of encapsulation than is public derivation. <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading27"></A><FONT COLOR="#000077">Friend Class</FONT></H3><P>Declare one class to be a friend of another by putting the word <TT>friend</TT>into the class granting the access rights. That is, I can declare you to be my friend,but you can't declare yourself to be my friend. Example:</P><PRE><FONT COLOR="#0066FF">class PartNode{public:friend class PartList;  // declares PartList to be a friend of PartNode};</FONT></PRE><H3 ALIGN="CENTER"><A NAME="Heading28"></A><FONT COLOR="#000077">Friend Fun

⌨️ 快捷键说明

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