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

📄 00000002.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 3 页
字号:
&nbsp;<BR>这可不是对&nbsp;Smalltalk&nbsp;恐怖份子挑□,让他们趁我熟睡时戳我的轮胎(在我很难得&nbsp;<BR>有空休息的这段时间内&nbsp;:-)&nbsp;。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q89:C++&nbsp;和&nbsp;Smalltalk&nbsp;的差别在哪?&nbsp;<BR>&nbsp;<BR>最重要的不同是:&nbsp;<BR>&nbsp;<BR>&nbsp;*&nbsp;静态型别或动态型别?&nbsp;<BR>&nbsp;*&nbsp;继承只能用於产生子型别上?&nbsp;<BR>&nbsp;*&nbsp;数值语意还是参考语意&nbsp;(value&nbsp;vs&nbsp;reference&nbsp;semantics)?&nbsp;<BR>&nbsp;<BR>头两个差异会在这一节中解释,第三点则是下一节的讨论主题。&nbsp;<BR>&nbsp;<BR>如果你是&nbsp;Smalltalk&nbsp;程式者,现在想学&nbsp;C++,底下三则&nbsp;FAQs&nbsp;最好仔细研读。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q90:什麽是「静态型别」?它和&nbsp;Smalltalk&nbsp;有多相似/不像?&nbsp;<BR>&nbsp;<BR>静态型别(static&nbsp;typing)是说:编译器会“静态地”(於编译时期)检验各运算&nbsp;<BR>的型态安全性,而不是产生执行时才会去检查的程式码。例如,在静态型别之下,会&nbsp;<BR>去侦测比对函数引数的型态签名,不正确的配对会被编译器挑出错误来,而非在执行&nbsp;<BR>时才被挑出。&nbsp;<BR>&nbsp;<BR>OO&nbsp;的程式里,最常见的「型态不符」错误是:欲对某物件启动个成员函数,但该物&nbsp;<BR>件并未准备好要处理该运算动作。譬如,如果&nbsp;&quot;Fred&quot;&nbsp;类别有成员函数&nbsp;&quot;f()&quot;&nbsp;但没&nbsp;<BR>有&nbsp;&quot;g()&quot;,且&nbsp;&quot;fred&quot;&nbsp;是&nbsp;&quot;Fred&quot;&nbsp;类别的案例,那麽&nbsp;&quot;fred.f()&quot;&nbsp;就是合法的,&nbsp;<BR>&quot;fred.g()&quot;&nbsp;则是非法的。C++(静态地)在编译期捕捉型别错误,Smalltalk&nbsp;则(动&nbsp;<BR>态地)在执行期捕捉。(技术上,C++&nbsp;很像&nbsp;Pascal--“半”静态型别--因为指&nbsp;<BR>标转型与&nbsp;union&nbsp;都能用来破坏型别系统;这提醒了我们:你用指标转型与&nbsp;union&nbsp;的&nbsp;<BR>频率,只能像你用&nbsp;&quot;goto&quot;&nbsp;那样。)&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q91:「静态型别」与「动态型别」哪一种比较适合&nbsp;C++?&nbsp;<BR>&nbsp;<BR>若你想最有效率使用&nbsp;C++,请把她当成静态型别语言来用。&nbsp;<BR>&nbsp;<BR>C++&nbsp;极富弹性,你可以(藉由指标转型、union&nbsp;或&nbsp;#define)让她「长得」像&nbsp;<BR>Smalltalk。但是不要这样做。这提醒了我们:少用&nbsp;#define。&nbsp;<BR>&nbsp;<BR>有些场合,指标转型和&nbsp;union&nbsp;是必要的,甚至是很好的做法,但须谨慎为之。指标&nbsp;<BR>转型等於是叫编译器完全信赖你。错误的指标转型可能会毁坏堆积、在别的物件记忆&nbsp;<BR>体中乱搞、呼叫不存在的运作行为、造成一般性错误(general&nbsp;failure)。这是很&nbsp;<BR>糟糕的事。如果你避免用与这些相关的东西,你的&nbsp;C++&nbsp;程式会更安全、更快,因为&nbsp;<BR>能在编译期就检测的东西,就不必留到执行期再做。&nbsp;<BR>&nbsp;<BR>就算你喜欢动态型别,也请避免在&nbsp;C++&nbsp;里使用,或者请考虑换另一个将型态检查延&nbsp;<BR>迟到执行期才做的语言。C++&nbsp;将型态检验&nbsp;100%&nbsp;都放在编译时期;她没有任何执行期&nbsp;<BR>型态检验的内建机制。如果你把&nbsp;C++&nbsp;当成一个动态型别的&nbsp;OOPL&nbsp;来用,你的命运将&nbsp;<BR>操之汝手。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q92:怎样分辨某个&nbsp;C++&nbsp;物件程式库是否属於动态型别的?&nbsp;<BR>&nbsp;<BR>提示&nbsp;#1:当所有东西都衍生自单一的根类别(root&nbsp;class),通常叫做&nbsp;&quot;Object&quot;。&nbsp;<BR>提示&nbsp;#2:当容器类别&nbsp;container&nbsp;classes,像&nbsp;List、Stack、Set&nbsp;等,都不是&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;版的。&nbsp;<BR>提示&nbsp;#3:当容器类别(List、Stack、Set&nbsp;等)把插入/取出的元素,都视为指向&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Object&quot;&nbsp;的指标时。(你可以把&nbsp;Apple&nbsp;放进容器中,但当你取出时,编&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;译器只知道它是衍生自&nbsp;Object,所以你得用指标转型将它转回&nbsp;Apple*&nbsp;;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;你最好祈祷它真的是个&nbsp;Apple,否则你会脑充血的。)&nbsp;<BR>&nbsp;<BR>你可用&nbsp;&quot;dynamic_cast&quot;(於&nbsp;1994&nbsp;年才加入的)来使指标转型「安全些」,但这种&nbsp;<BR>动态测试依旧是“动态”的。这种程式风格是&nbsp;C++&nbsp;动态型别的基本要素,你可以呼&nbsp;<BR>叫函数:「把这个&nbsp;Object&nbsp;转换成&nbsp;Apple,或是给我个&nbsp;NULL,如果它不是&nbsp;Apple的&nbsp;<BR>话」,你就得到动态型别了:直到执行时期才知道会发生什麽事。&nbsp;<BR>&nbsp;<BR>若你用&nbsp;template&nbsp;去实作出容器类别,C++&nbsp;编译器会静态侦测出&nbsp;99%&nbsp;的型态资讯(&nbsp;<BR>&quot;99%&quot;&nbsp;并不是真的;有些人宣称能做到&nbsp;100%,而那些需要持续性&nbsp;(persistence)&nbsp;的&nbsp;<BR>人,只能得到低於&nbsp;100%&nbsp;的静态型别检验)。重点是:C++&nbsp;透过&nbsp;template&nbsp;来做到泛&nbsp;<BR>型(genericity),而非透过继承。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q93:在&nbsp;C++&nbsp;里怎样用继承?它和&nbsp;Smalltalk&nbsp;有何不同?&nbsp;<BR>&nbsp;<BR>有些人认为继承是用来重用程式码的。在&nbsp;C++&nbsp;中,这是不对的。说明白点,「继承&nbsp;<BR>不是『为』重用程式码而设计的。」&nbsp;<BR>&nbsp;<BR>【译注】这一个分野相当重要。否则,C++&nbsp;使用者就会感染「继承发烧症」&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inheritance&nbsp;fever)。&nbsp;<BR>&nbsp;<BR>C++&nbsp;继承的目的是用来表现介面一致性(产生子类别),而不是重用程式码。C++&nbsp;中&nbsp;<BR>,重用程式码通常是靠「成份」(composition)&nbsp;而非继承。换句话说,继承主要是用&nbsp;<BR>来当作「特异化」(specialization)&nbsp;的技术,而非实作上的技巧。&nbsp;<BR>&nbsp;<BR>这是与&nbsp;Smalltalk&nbsp;主要的不同之处,在&nbsp;Smalltalk&nbsp;里只有一种继承的型式(C++&nbsp;有&nbsp;<BR>&quot;private&quot;&nbsp;继承--「共享程式码,但不承袭其介面」,有&nbsp;&quot;public&quot;&nbsp;继承--表现&nbsp;<BR>&quot;kind-of&quot;&nbsp;关系)。Smalltalk&nbsp;语言非常(相对於只是程式的习惯)允许你置放一个&nbsp;<BR>override&nbsp;覆盖(它会去呼叫个「我看不懂」的运作行为),以达到「隐藏住」继承&nbsp;<BR>下来的运作行为的“效果”。更进一步,Smalltalk&nbsp;可让观念界的&nbsp;&quot;is-a&quot;&nbsp;关系“独&nbsp;<BR>立於”子类别阶层之外(子型别不必也是子类别;譬如,你可以让某个东西是一个&nbsp;<BR>Stack,却不必继承自&nbsp;Stack&nbsp;类别)。&nbsp;<BR>&nbsp;<BR>相反的,C++&nbsp;对继承的限制更严:没办法不用到继承就做出“观念上的&nbsp;is-a”关系&nbsp;<BR>(有个&nbsp;C++&nbsp;的解决方法:透过&nbsp;ABC&nbsp;来分离介面与实作)。C++&nbsp;编译器利用公共继承&nbsp;<BR>额外附的语意资讯,以提供静态型别。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q94:Smalltalk/C++&nbsp;不同的继承,在现实里导致的结果是什麽?&nbsp;<BR>&nbsp;<BR>Smalltalk&nbsp;让你做出不是子类别的子型别,做出不是子型别的子类别,它可让&nbsp;<BR>Smalltalk&nbsp;程式者不必操心该把哪种资料(位元、表现型式、资料结构)放进类别里&nbsp;<BR>面(譬如,你可能会把连结串列放到堆叠类别里)。毕竟,如果有人想要个以阵列做&nbsp;<BR>出的堆叠,他不必真的从堆叠继承过来;喜欢的话,他可以从阵列类别&nbsp;Array&nbsp;中继&nbsp;<BR>承过来,即使&nbsp;ArrayBasedStack&nbsp;并“不是”一种阵列!)&nbsp;<BR>&nbsp;<BR>在&nbsp;C++&nbsp;中,你不可能不为此操心。只有机制(运作行为的程式码),而非表现法(&nbsp;<BR>资料位元)可在子类别中被覆盖掉,所以,通常你“不要”把资料结构放进类别里比&nbsp;<BR>较好。这会促成&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs)&nbsp;的强烈使用需求。&nbsp;<BR>&nbsp;<BR>我喜欢用&nbsp;ATV&nbsp;和&nbsp;Maseratti&nbsp;之间的差别来比喻。ATV(all&nbsp;terrain&nbsp;vehicle,越野&nbsp;<BR>车)很好玩,因为你可以「到处逛」,任意开到田野、小溪、人行道等地。另一方面&nbsp;<BR>,Maseratti&nbsp;让你能高速行驶,但你只能在公路上面开。就算你喜欢「自由表现力」&nbsp;<BR>,偏偏喜欢驶向丛林,但也请不要在&nbsp;C++&nbsp;里这麽做;它不适合。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q95:学过「纯种」的&nbsp;OOPL&nbsp;之後才能学&nbsp;C++&nbsp;吗?&nbsp;<BR>&nbsp;<BR>不是(事实上,这样可能反而会害了你)。&nbsp;<BR>&nbsp;<BR>(注意:Smalltalk&nbsp;是个「纯种」的&nbsp;OOPL,而&nbsp;C++&nbsp;是个「混血」的&nbsp;OOPL。)读这&nbsp;<BR>之前,请先读读前面关於&nbsp;C++&nbsp;与&nbsp;Smalltalk&nbsp;差别的&nbsp;FAQs。&nbsp;<BR>&nbsp;<BR>OOPL&nbsp;的「纯粹性」,并不会让转移到&nbsp;C++&nbsp;更容易些。事实上,典型的动态系结与非&nbsp;<BR>子型别的继承,会让&nbsp;Smalltalk&nbsp;程式者更难学会&nbsp;C++。Paradigm&nbsp;Shift&nbsp;公司曾教过&nbsp;<BR>数千人&nbsp;OO&nbsp;技术,我们注意到:有&nbsp;Smalltalk&nbsp;背景的人来学&nbsp;C++,通常和那些根本&nbsp;<BR>没碰过继承的人学起来差不多累。事实上,对动态型别的&nbsp;OOPL(通常是,但不全都&nbsp;<BR>是&nbsp;Smalltalk)有高度使用经验的人,可能会“更难”学好,因为想把过去的习惯“&nbsp;<BR>遗忘”,会比一开始就学习静态型别来得困难。&nbsp;<BR>&nbsp;<BR>【译注】作者是以「语言学习」的角度来看的。事实上,若先有&nbsp;Smalltalk&nbsp;之类的&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;物件导向观念的背景知识,再来学&nbsp;C++&nbsp;就不必再转换&nbsp;&quot;paradigm&quot;--物件&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;导向的中心思维是不会变的,变的只是实行细节而已。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q96:什麽是&nbsp;NIHCL?到哪里拿到它?&nbsp;<BR>&nbsp;<BR>NIHCL&nbsp;代表&nbsp;&quot;national-institute-of-health's-class-library&quot;,美国国家卫生局&nbsp;<BR>物件程式库。取得法:anonymous&nbsp;ftp&nbsp;到&nbsp;[128.231.128.7],&nbsp;<BR>档案:pub/nihcl-3.0.tar.Z&nbsp;。&nbsp;<BR>&nbsp;<BR>NIHCL(有人念作&nbsp;&quot;N-I-H-C-L&quot;,有人念作&nbsp;&quot;nickel&quot;)是个由&nbsp;Smalltalk&nbsp;转移过来&nbsp;<BR>的&nbsp;C++&nbsp;物件程式库。有些&nbsp;NIHCL&nbsp;用到的动态型别很棒(譬如:persistent&nbsp;objects&nbsp;<BR>,持续性物件),也有些地方动态型别会和&nbsp;C++&nbsp;语言的静态型别相冲突,造成紧张&nbsp;<BR>关系。&nbsp;<BR>&nbsp;<BR>详见前面关於&nbsp;Smalltalk&nbsp;的&nbsp;FAQs。&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>===============================&nbsp;<BR>■□&nbsp;第16节:参考与数值语意&nbsp;<BR>===============================&nbsp;<BR>&nbsp;<BR>Q97:什麽是数值以及参考语意?哪一种在&nbsp;C++&nbsp;里最好?&nbsp;<BR>&nbsp;<BR>在参考语意&nbsp;(reference&nbsp;semantics)&nbsp;中,「设定」是个「指标拷贝」的动作(也就&nbsp;<BR>是“参考”这个词的本意),数值语意&nbsp;(value&nbsp;semantics,或&nbsp;&quot;copy&quot;&nbsp;semantics)&nbsp;<BR>的设定则是真正地「拷贝其值」,而不是做指标拷贝的动作。C++&nbsp;让你选择:用设定&nbsp;<BR>运算子来拷贝其值(copy/value&nbsp;语意),或是用指标拷贝方式来拷贝指标&nbsp;<BR>(reference&nbsp;语意)。C++&nbsp;让你能覆盖掉&nbsp;(override)&nbsp;设定运算子,让它去做你想要&nbsp;<BR>的事,不过系统预设的(而且是最常见的)方式是拷贝其「数值」。&nbsp;<BR>&nbsp;<BR>参考语意的优点:弹性、动态系结(在&nbsp;C++&nbsp;里,你只能以传指标或传参考来达到动&nbsp;<BR>态系结,而不是用传值的方式)。&nbsp;<BR>&nbsp;<BR>数值语意的优点:速度。对需要物件(而非指标)的场合来说,「速度」似乎是很奇&nbsp;<BR>怪的特点,但事实上,我们比较常存取物件本身,较不常去拷贝它。所以偶尔的拷贝&nbsp;<BR>所付出的代价,(通常)会被拥有「真正的物件本身」、而非仅是指向物件的指标所&nbsp;<BR>带来的效益弥补过去。&nbsp;<BR>&nbsp;<BR>有三个情况,你会得到真正的物件,而不是指向它的指标:区域变数、整体/静态变&nbsp;<BR>数、完全被某类别包含在内&nbsp;(fully&nbsp;contained)&nbsp;的成员物件。这里头最重要的就是&nbsp;<BR>最後一个(也就是「成份」)。&nbsp;<BR>&nbsp;<BR>後面的&nbsp;FAQs&nbsp;会有更多关於&nbsp;copy-vs-reference&nbsp;语意的资讯,请全部读完,以得到&nbsp;<BR>较平衡的观点。前几则会刻意偏向数值语意,所以若你只读前面的,你的观点就会有&nbsp;<BR>所偏颇。&nbsp;<BR>&nbsp;<BR>设定&nbsp;(assignment)&nbsp;还有别的事项(譬如:shallow&nbsp;vs&nbsp;deep&nbsp;copy)没在这儿提到。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q98:「虚拟资料」是什麽?怎麽样/为什麽该在&nbsp;C++&nbsp;里使用它?&nbsp;<BR>

⌨️ 快捷键说明

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