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

📄 00000001.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;<BR>以私有衍生类别的运作行为、夥伴来看,从它上溯到基底类别的关系为已知的,所以&nbsp;<BR>从&nbsp;PrivatelyDer*&nbsp;往上转换成&nbsp;Base*(或是从&nbsp;PrivatelyDer&amp;&nbsp;到&nbsp;Base&amp;)是安全的&nbsp;<BR>;强制转型是不需要也不鼓励的。&nbsp;<BR>&nbsp;<BR>然而用&nbsp;PrivateDer&nbsp;的人应该避免这种不安全的转换,因为此乃立足於&nbsp;PrivateDer&nbsp;<BR>的&nbsp;&quot;private&quot;&nbsp;决定,这个决定很容易在日後不经察觉就改变了。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q72:保护继承&nbsp;(protected&nbsp;inheritance)&nbsp;和私有继承有何关连?&nbsp;<BR>&nbsp;<BR>相似处:两者都能覆盖掉私有/保护基底类别的虚拟函数,两者都不把衍生的类别视&nbsp;<BR>为“一种”基底类别。&nbsp;<BR>&nbsp;<BR>不相似处:保护继承可让衍生类别的衍生类别知道它的继承关系(把实行细节显现出&nbsp;<BR>来)。它有好处(允许保护继承类别的子类别,藉这项关系来使用保护基底类别),&nbsp;<BR>也有代价(保护继承的类别,无法既想改变这种关系,而又不破坏到进一步的衍生类&nbsp;<BR>别)。&nbsp;<BR>&nbsp;<BR>保护继承使用&nbsp;&quot;:&nbsp;protected&quot;&nbsp;这种语法:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Car&nbsp;:&nbsp;protected&nbsp;Engine&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q73:&quot;private&quot;&nbsp;和&nbsp;&quot;protected&quot;&nbsp;的存取规则是什麽?&nbsp;<BR>&nbsp;<BR>拿底下这些类别当例子:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;/*...*/&nbsp;};&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;D_priv&nbsp;:&nbsp;private&nbsp;&nbsp;&nbsp;B&nbsp;{&nbsp;/*...*/&nbsp;};&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;D_prot&nbsp;:&nbsp;protected&nbsp;B&nbsp;{&nbsp;/*...*/&nbsp;};&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;D_publ&nbsp;:&nbsp;public&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;{&nbsp;/*...*/&nbsp;};&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;UserClass&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;B&nbsp;b;&nbsp;/*...*/&nbsp;};&nbsp;<BR>&nbsp;<BR>没有一个子类别能存取到&nbsp;B&nbsp;的&nbsp;private&nbsp;部份。&nbsp;<BR>在&nbsp;D_priv&nbsp;内,B&nbsp;的&nbsp;public&nbsp;和&nbsp;protected&nbsp;部份都变成&nbsp;&quot;private&quot;。&nbsp;<BR>在&nbsp;D_prot&nbsp;内,B&nbsp;的&nbsp;public&nbsp;和&nbsp;protected&nbsp;部份都变成&nbsp;&quot;protected&quot;。&nbsp;<BR>在&nbsp;D_publ&nbsp;内,B&nbsp;的&nbsp;public&nbsp;部份还是&nbsp;public,protected&nbsp;还是&nbsp;protected&nbsp;<BR>&nbsp;(D_publ&nbsp;is-a-kind-of-a&nbsp;B)&nbsp;。&nbsp;<BR>Class&nbsp;&quot;UserClass&quot;&nbsp;只能存取&nbsp;B&nbsp;的&nbsp;public&nbsp;部份,也就是:把&nbsp;UserClass&nbsp;从&nbsp;B&nbsp;那&nbsp;<BR>儿封起来了。&nbsp;<BR>&nbsp;<BR>欲把&nbsp;B&nbsp;的&nbsp;public&nbsp;成员在&nbsp;D_priv&nbsp;或&nbsp;D_prot&nbsp;内也变成&nbsp;public,只要在该成员的名&nbsp;<BR>字前面加上&nbsp;&quot;B::&quot;。譬如:想让&nbsp;&quot;B::f(int,float)&quot;&nbsp;成员在&nbsp;D_prot&nbsp;内也是&nbsp;public&nbsp;<BR>的话,照这样写:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;D_prot&nbsp;:&nbsp;protected&nbsp;B&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B::f;&nbsp;&nbsp;&nbsp;&nbsp;//注意:不是写成&nbsp;&quot;B::f(int,float)&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>======================================&nbsp;<BR>■□&nbsp;第13节:抽象化(abstraction)&nbsp;<BR>======================================&nbsp;<BR>&nbsp;<BR>Q74:分离介面与实作是做什麽用的?&nbsp;<BR>&nbsp;<BR>介面是企业体最有价值的资源。设计介面会比只把一堆独立的类别拼凑起来来得耗时&nbsp;<BR>,尤其是:介面需要花费更高阶人力的时间。&nbsp;<BR>&nbsp;<BR>既然介面是如此重要,它就应该保护起来,以避免被资料结构等等实作细节之变更所&nbsp;<BR>影响。因此你应该将介面与实作分离开来。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q75:在&nbsp;C++&nbsp;里,我该怎样分离介面与实作(像&nbsp;Modula-2&nbsp;那样)?&nbsp;<BR>&nbsp;<BR>用&nbsp;ABC(见下一则&nbsp;FAQ)。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q76:ABC&nbsp;(&quot;abstract&nbsp;base&nbsp;class&quot;)&nbsp;是什麽?&nbsp;<BR>&nbsp;<BR>在设计层面,ABC&nbsp;对应到抽象的概念。如果你问机械师父说他修不修运输工具,他可&nbsp;<BR>能会猜你心中想的到底是“哪一种”运输工具,他可能不会修理太空梭、轮船、脚踏&nbsp;<BR>车、核子潜艇。问题在於:「运输工具」是个抽象的概念(譬如:你建不出一辆「运&nbsp;<BR>输工具」,除非你知道要建的是“哪一种”)。在&nbsp;C++,运输工具类别可当成是一个&nbsp;<BR>ABC,而脚踏车、太空梭……等等都当做它的子类别(轮船“是一种”运输工具)。&nbsp;<BR>在真实世界的&nbsp;OOP&nbsp;中,ABC&nbsp;观念到处都是。&nbsp;<BR>&nbsp;<BR>在程式语言层面,ABC&nbsp;是有一个以上纯虚拟成员函数(pure&nbsp;virtual)的类别(详见&nbsp;<BR>下一则&nbsp;FAQ),你无法替一个&nbsp;ABC&nbsp;建造出物件(案例)来。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q77:「纯虚拟」(pure&nbsp;virtual)&nbsp;成员函数是什麽?&nbsp;<BR>&nbsp;<BR>ABC&nbsp;的某种成员函数,你只能在衍生的类别中实作它。&nbsp;<BR>&nbsp;<BR>有些成员函数只存於观念中,没有任何实质的定义。譬如,假设我要你画个&nbsp;Shape,&nbsp;<BR>它位於&nbsp;(x,y),大小为&nbsp;7。你会问我「我该画哪一种&nbsp;shape?」(圆、方、六边……&nbsp;<BR>都有不同的画法。)在&nbsp;C++&nbsp;里,我们可以先标出有一个叫做&nbsp;&quot;draw()&quot;&nbsp;这样的运作&nbsp;<BR>行为,且规定它只能(逻辑上)在子类别中定义出来:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Shape&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;draw()&nbsp;const&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^^^---&nbsp;&quot;=&nbsp;0&quot;&nbsp;指:它是&nbsp;&quot;pure&nbsp;virtual&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>此纯虚拟函数让&nbsp;&quot;Shape&quot;&nbsp;变成一个&nbsp;ABC。若你愿意,你可以把&nbsp;&quot;=&nbsp;0&quot;&nbsp;语法想成是:&nbsp;<BR>该程式码是位於&nbsp;NULL&nbsp;指标处。因此,&quot;Shape&quot;&nbsp;提供一个服务项目,但它现在尚无法&nbsp;<BR>提供实质的程式码以实现之。这样会确保:任何由&nbsp;Shape&nbsp;衍生出的&nbsp;[具体的]&nbsp;类别&nbsp;<BR>之物件,“将会”有那个我们事先规定的成员函数,即使基底类别尚无足够的资讯去&nbsp;<BR>真正的“定义”它。&nbsp;<BR>&nbsp;<BR>【译注】此处「定义」、「宣告」二词要分辨清楚!&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q78:怎样替整个类别阶层提供列印的功能?&nbsp;<BR>&nbsp;<BR>提供一个&nbsp;friend&nbsp;operator&lt;&lt;&nbsp;去呼叫&nbsp;protected&nbsp;的虚拟函数:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Base&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;ostream&amp;&nbsp;operator&lt;&lt;&nbsp;(ostream&amp;&nbsp;o,&nbsp;const&nbsp;Base&amp;&nbsp;b)&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;b.print(o);&nbsp;return&nbsp;o;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;print(ostream&amp;&nbsp;o)&nbsp;const;&nbsp;&nbsp;//或&nbsp;&quot;=0;&quot;&nbsp;若&nbsp;&quot;Base&quot;&nbsp;是个&nbsp;ABC&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Derived&nbsp;:&nbsp;public&nbsp;Base&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;print(ostream&amp;&nbsp;o)&nbsp;const;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>这样子所有&nbsp;Base&nbsp;的子类别只须提供它们自己的&nbsp;&quot;print(ostream&amp;)&nbsp;const&quot;&nbsp;成员函&nbsp;<BR>数即可(它们都共用&nbsp;&quot;&lt;&lt;&quot;&nbsp;operator)。这种技巧让夥伴像是有了动态系结的能力。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q79:何时该把解构子弄成&nbsp;virtual?&nbsp;<BR>&nbsp;<BR>当你可能经由基底的指标去&nbsp;&quot;delete&quot;&nbsp;掉衍生的类别时。&nbsp;<BR>&nbsp;<BR>虚拟函数把某物件所属之真正类别所附的程式码,而非该指标/参考本身之类别所附&nbsp;<BR>的程式给系结上去。&nbsp;当你说&nbsp;&quot;delete&nbsp;basePtr&quot;,且它的基底有虚拟解构子的话,则&nbsp;<BR>真正会被呼叫到的解构子,就是&nbsp;*basePtr&nbsp;物件之型态所属的解构子,而不是该指标&nbsp;<BR>本身之型态所附的解构子。一般说来这的确是一件好事。&nbsp;<BR>&nbsp;<BR>让你方便起见,你唯一不必将某类别的解构子设为&nbsp;virtual&nbsp;的场合是:「该类别“&nbsp;<BR>没有”任何虚拟函数」。因为加入第一个虚拟函数,就会替每个物件都添加额外的空&nbsp;<BR>间负担(通常是一个机器&nbsp;word&nbsp;的大小),这正是编译器实作出动态系结的□密;它&nbsp;<BR>通常会替每个物件加入额外的指标,称为「虚拟指标表格」(virtual&nbsp;table&nbsp;pointer)&nbsp;<BR>,或是&nbsp;&quot;vptr&quot;&nbsp;。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q80:虚拟建构子&nbsp;(virtual&nbsp;constructor)&nbsp;是什麽?&nbsp;<BR>&nbsp;<BR>一种让你能做些&nbsp;C++&nbsp;不直接支援的事情之惯用法。&nbsp;<BR>&nbsp;<BR>欲做出虚拟建构子的效果,可用个虚拟的&nbsp;&quot;createCopy()&quot;&nbsp;成员函数(用来做为拷贝&nbsp;<BR>建构子),或是虚拟的&nbsp;&quot;createSimilar()&quot;&nbsp;成员函数(用来做为预设建构子)。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Shape&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~Shape()&nbsp;{&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//详见&nbsp;&quot;virtual&nbsp;destructors&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;draw()&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;move()&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;Shape*&nbsp;createCopy()&nbsp;const&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;Shape*&nbsp;createSimilar()&nbsp;const&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Circle&nbsp;:&nbsp;public&nbsp;Shape&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Circle*&nbsp;createCopy()&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;{&nbsp;return&nbsp;new&nbsp;Circle(*this);&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Circle*&nbsp;createSimilar()&nbsp;const&nbsp;{&nbsp;return&nbsp;new&nbsp;Circle();&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>执行了&nbsp;&quot;Circle(*this)&quot;&nbsp;也就是执行了拷贝建构的行为(在这些

⌨️ 快捷键说明

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