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

📄 00000001.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q42:怎样确保某类别的物件都是用&nbsp;&quot;new&quot;&nbsp;建立的,而非区域或整体/静态变数?&nbsp;<BR>&nbsp;<BR>确定该类别的建构子都是&nbsp;&quot;private:&quot;&nbsp;的,并定义个&nbsp;&quot;friend&quot;&nbsp;或&nbsp;&quot;static&quot;&nbsp;函数,&nbsp;<BR>来传回一个指向由&nbsp;&quot;new&quot;&nbsp;建造出来的物件(把建构子设成&nbsp;&quot;protected:&quot;,如果你想&nbsp;<BR>要有衍生类别的话)。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Fred&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;//只允许&nbsp;Fred&nbsp;动态地配置出来&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;Fred*&nbsp;create()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;return&nbsp;new&nbsp;Fred();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;Fred*&nbsp;create(int&nbsp;i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;return&nbsp;new&nbsp;Fred(i);&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;Fred*&nbsp;create(const&nbsp;Fred&amp;&nbsp;fred)&nbsp;{&nbsp;return&nbsp;new&nbsp;Fred(fred);&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fred();&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fred(int&nbsp;i);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fred(const&nbsp;Fred&amp;&nbsp;fred);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~Fred();&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;main()&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fred*&nbsp;p&nbsp;=&nbsp;Fred::create(5);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;p;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>===============================&nbsp;<BR>■□&nbsp;第10节:除错与错误处理&nbsp;<BR>===============================&nbsp;<BR>&nbsp;<BR>Q43:怎样处理建构子的错误?&nbsp;<BR>&nbsp;<BR>丢出一个例外(throw&nbsp;an&nbsp;exception)。&nbsp;<BR>&nbsp;<BR>建构子没有传回值,所以不可能采用它传回的错误码。因此,侦测建构子错误最好的&nbsp;<BR>方法,就是丢出一个例外。&nbsp;<BR>&nbsp;<BR>在&nbsp;C++&nbsp;编译器尚未提供例外处理之前,我们可先把物件置於「半熟」的状态(譬如&nbsp;<BR>:设个内部的状态位元),用个查询子(&quot;inspector&quot;)来检查该位元,就可让用户&nbsp;<BR>查看该物件是否还活著。也可以用另一个成员函数来检查该位元,若该物件没存活&nbsp;<BR>下来,就做个「没动作」(或是更狠的像是&nbsp;&quot;abort()&quot;&nbsp;)的程式。但这实在很丑陋。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q44:如果建构子会丢出例外的话,该怎麽处理它的资源?&nbsp;<BR>&nbsp;<BR>物件里面的每个资料成员,都该自己收拾残局。&nbsp;<BR>&nbsp;<BR>如果建构子丢出一个例外的话,该物件的解构子就“不会”执行。如果你的物件得回&nbsp;<BR>复些曾做过的事情(像是配置记忆体、开启档案、锁定&nbsp;semaphore),该物件内的资&nbsp;<BR>料成员就“必须”记住这个「必须恢复的东西」。&nbsp;<BR>&nbsp;<BR>举例来说:不要单单的把配置到的记忆体放入&nbsp;&quot;Fred*&quot;&nbsp;资料成员,而要放入一个「&nbsp;<BR>聪明的指标」(smart&nbsp;pointer)&nbsp;资料成员中;当该“聪明指标”死掉的话,它的解构&nbsp;<BR>子就会删去&nbsp;Fred&nbsp;物件。&nbsp;<BR>&nbsp;<BR>【译注】「聪明的指标」(smart&nbsp;pointer)&nbsp;在&nbsp;Q4&nbsp;中有提到一点。&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>=============================&nbsp;<BR>■□&nbsp;第11节:Const&nbsp;正确性&nbsp;<BR>=============================&nbsp;<BR>&nbsp;<BR>Q45:什麽是&nbsp;&quot;const&nbsp;correctness&quot;?&nbsp;<BR>&nbsp;<BR>好问题。&nbsp;<BR>&nbsp;<BR>「常数正确性」乃使用&nbsp;&quot;const&quot;&nbsp;关键字,以确保常数物件不会被更动到。譬如:若&nbsp;<BR>&quot;f()&quot;&nbsp;函数接收一个&nbsp;&quot;String&quot;,且&nbsp;&quot;f()&quot;&nbsp;想确保&nbsp;&quot;String&quot;&nbsp;不会被改变,你可以:&nbsp;<BR>&nbsp;<BR>&nbsp;*&nbsp;传值呼叫&nbsp;(pass&nbsp;by&nbsp;value):&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;&nbsp;f(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;&nbsp;s&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;{&nbsp;/*...*/&nbsp;}&nbsp;<BR>&nbsp;*&nbsp;透过常数参考&nbsp;(reference):&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;&nbsp;f(const&nbsp;String&amp;&nbsp;s&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;{&nbsp;/*...*/&nbsp;}&nbsp;<BR>&nbsp;*&nbsp;透过常数指标&nbsp;(pointer)&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;&nbsp;f(const&nbsp;String*&nbsp;sptr)&nbsp;&nbsp;{&nbsp;/*...*/&nbsp;}&nbsp;<BR>&nbsp;*&nbsp;但不能用非常数参考&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;&nbsp;f(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&amp;&nbsp;s&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;{&nbsp;/*...*/&nbsp;}&nbsp;<BR>&nbsp;*&nbsp;也不能用非常数指标&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;&nbsp;f(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String*&nbsp;sptr)&nbsp;&nbsp;{&nbsp;/*...*/&nbsp;}&nbsp;<BR>&nbsp;<BR>在接收&nbsp;&quot;const&nbsp;String&amp;&quot;&nbsp;参数的函数里面,想更动到&nbsp;&quot;s&quot;&nbsp;的话,会产生个编译期的&nbsp;<BR>错误;没有牺牲任何执行期的空间及速度。&nbsp;<BR>&nbsp;<BR>宣告&nbsp;&quot;const&quot;&nbsp;参数也是另一种型别安全方法,就像一个常数字串,它会“丧失”各&nbsp;<BR>种可能会变更其内容的行为动作。如果你发现型别安全性质让你的系统正确地运作&nbsp;<BR>(这是真的;特别是大型的系统),你会发现「常数正确性」亦如是。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q46:我该早一点还是晚一点让东西有常数正确性?&nbsp;<BR>&nbsp;<BR>越越越早越好。&nbsp;<BR>&nbsp;<BR>延後补以常数正确性,会导致雪球效应:每次你在「这儿」用了&nbsp;&quot;const&quot;,你就得在&nbsp;<BR>「那儿」加上四个以上的&nbsp;&quot;const&quot;。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q47:什麽是「const&nbsp;成员函数」?&nbsp;<BR>&nbsp;<BR>一个只检测(而不更动)其物件的成员函数。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;Fred&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;f()&nbsp;const;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;^^^^^---&nbsp;暗示说&nbsp;&quot;fred.f()&quot;&nbsp;不会改变到&nbsp;&quot;fred&quot;&nbsp;<BR>&nbsp;<BR>此乃意指:「抽象层次」的(用户可见的)物件状态不被改变(而不是许诺:该物件&nbsp;<BR>的「每一个位元内容」都不会被动到)。C++&nbsp;编译器不会对你许诺「每一个位元」这&nbsp;<BR>种事情,因为不是常数的别名(alias)就可能会修改物件的状态(把&nbsp;&quot;const&quot;&nbsp;指标&nbsp;<BR>黏上某个物件,并不能担保该物件不被改变;它只能担保该物件不会「被该指标的动&nbsp;<BR>作」所改变)。&nbsp;<BR>&nbsp;<BR>【译注】请逐字细读上面这句话。&nbsp;<BR>&nbsp;<BR>&quot;const&quot;&nbsp;成员函数常被称作「查询子」(inspector),不是&nbsp;&quot;const&quot;&nbsp;的成员函数则&nbsp;<BR>称为「更动子」(mutator)。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q48:若我想在&nbsp;&quot;const&quot;&nbsp;成员函数内更新一个「看不见的」资料成员,该怎麽做?&nbsp;<BR>&nbsp;<BR>使用&nbsp;&quot;mutable&quot;&nbsp;或是&nbsp;&quot;const_cast&quot;。&nbsp;<BR>【译注】这是很新的&nbsp;ANSI&nbsp;C++&nbsp;RTTI&nbsp;(RunTime&nbsp;Type&nbsp;Information)&nbsp;规定,Borland&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C++&nbsp;4.0&nbsp;就率先提供了&nbsp;const_cast&nbsp;运算子。&nbsp;<BR>&nbsp;<BR>少数的查询子需要对资料成员做些无害的改变(譬如:&quot;Set&quot;&nbsp;物件可能想快取它上一&nbsp;<BR>回所查到的东西,以加速下一次的查询)。此改变「无害」是指:此改变不会由物件&nbsp;<BR>的外部介面察觉出来(否则,该运作行为就该叫做更动子,而非查询子了)。&nbsp;<BR>&nbsp;<BR>这类情况下,会被更动的资料成员就该被标示成&nbsp;&quot;mutable&quot;(把&nbsp;&quot;mutable&quot;&nbsp;关键字&nbsp;<BR>放在该资料成员宣告处前面;也就是和你放&nbsp;&quot;const&quot;&nbsp;一样的地方),这会告诉编译&nbsp;<BR>器:此资料成员允许&nbsp;const&nbsp;成员函数改变之。若你不能用&nbsp;&quot;mutable&quot;&nbsp;的话,可以用&nbsp;<BR>&quot;const_cast&quot;&nbsp;把&nbsp;&quot;this&quot;&nbsp;的「常数性」给转型掉。譬如,在&nbsp;&quot;Set::lookup()&nbsp;const&quot;&nbsp;<BR>里,你可以说:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set*&nbsp;self&nbsp;=&nbsp;const_cast&lt;Set*&gt;(this);&nbsp;<BR>&nbsp;<BR>这行执行之後,&quot;self&quot;&nbsp;的位元内容就和&nbsp;&quot;this&quot;&nbsp;一样(譬如:&quot;self==this&quot;),但&nbsp;<BR>是&nbsp;&quot;self&quot;&nbsp;是一个&nbsp;&quot;Set*&quot;&nbsp;而非&nbsp;&quot;const&nbsp;Set*&quot;&nbsp;了,所以你就可以用&nbsp;&quot;self&quot;&nbsp;去修改&nbsp;<BR>&quot;this&quot;&nbsp;指标所指向的物件。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q49:&quot;const_cast&quot;&nbsp;会不会丧失最佳化的可能?&nbsp;<BR>&nbsp;<BR>理论上,是;实际上,否。&nbsp;<BR>&nbsp;<BR>就算编译器没真正做好&nbsp;&quot;const_cast&quot;,欲避免&nbsp;&quot;const&quot;&nbsp;成员函数被呼叫时,会造成&nbsp;<BR>暂存器快取区被清空的唯一方法,乃确保没有任何「非常数」的指标指向该物件。这&nbsp;<BR>种情况很难得会发生(当物件在&nbsp;const&nbsp;成员函数被启用的□围内被建立出来;当所&nbsp;<BR>有非&nbsp;const&nbsp;的成员函数在物件建立间启用,和&nbsp;const&nbsp;成员函数的启用被静态系结住&nbsp;<BR>;当所有的启用也都是&nbsp;&quot;inline&quot;;当建构子本身就是&nbsp;&quot;inline&quot;;和当建构子所呼叫&nbsp;<BR>的任何成员函数都是&nbsp;inline&nbsp;时)。&nbsp;<BR>&nbsp;<BR>【译注】这一段话很难翻得好(好啦好啦!我功力不足...&nbsp;:-&lt;&nbsp;),所以附上原文:&nbsp;<BR>Even&nbsp;if&nbsp;a&nbsp;compiler&nbsp;outlawed&nbsp;&quot;const_cast&quot;,&nbsp;the&nbsp;only&nbsp;way&nbsp;to&nbsp;avoid&nbsp;flushing&nbsp;<BR>the&nbsp;register&nbsp;cache&nbsp;across&nbsp;a&nbsp;&quot;const&quot;&nbsp;member&nbsp;function&nbsp;call&nbsp;would&nbsp;be&nbsp;to&nbsp;<BR>ensure&nbsp;that&nbsp;there&nbsp;are&nbsp;no&nbsp;non-const&nbsp;pointers&nbsp;that&nbsp;alias&nbsp;the&nbsp;object.&nbsp;&nbsp;This&nbsp;<BR>can&nbsp;only&nbsp;happen&nbsp;in&nbsp;rare&nbsp;cases&nbsp;(when&nbsp;the&nbsp;object&nbsp;is&nbsp;constructed&nbsp;in&nbsp;the&nbsp;scope&nbsp;<BR>of&nbsp;the&nbsp;const&nbsp;member&nbsp;fn&nbsp;invocation,&nbsp;and&nbsp;when&nbsp;all&nbsp;the&nbsp;non-const&nbsp;member&nbsp;<BR>function&nbsp;invocations&nbsp;between&nbsp;the&nbsp;object's&nbsp;construction&nbsp;and&nbsp;the&nbsp;const&nbsp;<BR>member&nbsp;fn&nbsp;invocation&nbsp;are&nbsp;statically&nbsp;bound,&nbsp;and&nbsp;when&nbsp;every&nbsp;one&nbsp;of&nbsp;these&nbsp;<BR>invocations&nbsp;is&nbsp;also&nbsp;&quot;inline&quot;d,&nbsp;and&nbsp;when&nbsp;the&nbsp;constructor&nbsp;itself&nbsp;is&nbsp;&quot;inline&quot;d,&nbsp;<BR>and&nbsp;when&nbsp;any&nbsp;member&nbsp;fns&nbsp;the&nbsp;constructor&nbsp;calls&nbsp;are&nbsp;inline).&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>=====================&nbsp;<BR>■□&nbsp;第12节:继承&nbsp;<BR>=====================&nbsp;<BR>&nbsp;<BR>Q50:「继承」对&nbsp;C++&nbsp;来说很重要吗?&nbsp;<BR>&nbsp;<BR>是的。&nbsp;<BR>&nbsp;<BR>「继承」是抽象化资料型态(abstract&nbsp;data&nbsp;type,&nbsp;ADT)与&nbsp;OOP&nbsp;的一大分野。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q51:何时该用继承?&nbsp;<BR>&nbsp;<BR>做为一个「特异化」(specialization)&nbsp;的机制。&nbsp;<BR>&nbsp;<BR>人类以两种角度来抽象化事物:「部份」(part-of)&nbsp;和「种类」(kind-of)。福特汽&nbsp;<BR>

⌨️ 快捷键说明

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