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

📄 00000003.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
Q110:为什麽我总觉得&nbsp;C++&nbsp;让我「离机器更远了」,不像&nbsp;C&nbsp;那样?&nbsp;<BR>&nbsp;<BR>因为事实上正是如此。&nbsp;<BR>&nbsp;<BR>做为一个&nbsp;OOPL,C++&nbsp;让你以该问题的领域来思考,让你以问题领域的语言来设计程&nbsp;<BR>式,而非以解题的领域来著手。&nbsp;<BR>&nbsp;<BR>一个&nbsp;C&nbsp;最强的地方是:它没有「隐藏的机制」:你看到的就是你得到的,你可以一&nbsp;<BR>边阅读&nbsp;C&nbsp;的程式,一边「看到」每个系统时脉。C++&nbsp;则不然;&nbsp;C&nbsp;的老手(像从前的&nbsp;<BR>我们)对这种特性常会有矛盾的心理(或是说「敌视」),但是很快的他们会发现:&nbsp;<BR>C++&nbsp;提供了抽象化的层次及经济的表现能力,大大降低维护成本,又不会损及执行效&nbsp;<BR>率。&nbsp;<BR>&nbsp;<BR>很自然的,用任何语言都会写出坏程式;C++&nbsp;并不会确保任何高品质、可重用性、抽&nbsp;<BR>象化,或是任何「正字标记」的品质因子。C++&nbsp;不会让差劲的程式者写不出差劲的程&nbsp;<BR>式;她只是协助明智的发展者做出高人一等的软体。&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>===================================&nbsp;<BR>■□&nbsp;第18节:指向成员函数的指标&nbsp;<BR>===================================&nbsp;<BR>&nbsp;<BR>Q111:「指向成员函数的指标」和「指到函数的指标」的型态有差别吗?&nbsp;<BR>&nbsp;<BR>是的。&nbsp;<BR>&nbsp;<BR>考虑底下的函数:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;f(char&nbsp;a,&nbsp;float&nbsp;b);&nbsp;<BR>&nbsp;<BR>如果它是普通的函数,它的型态是:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;(*)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(char,float);&nbsp;<BR>如果它是&nbsp;Fred&nbsp;类别的运作行为,它的型态是:&nbsp;&nbsp;int&nbsp;(Fred::*)(char,float);&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q112:怎样把指向成员函数的指标传给&nbsp;signal&nbsp;handler、X&nbsp;event&nbsp;callback&nbsp;等等?&nbsp;<BR>&nbsp;<BR>【译注】这是和&nbsp;UNIX、X&nbsp;Window&nbsp;System&nbsp;相关的问题,但其他系统亦可推而广之。&nbsp;<BR>&nbsp;<BR>不要这样做。&nbsp;<BR>&nbsp;<BR>因为若无物件去启动它,成员函数是无意义的,你不能直接使用它(如果&nbsp;X&nbsp;视窗系&nbsp;<BR>统是用&nbsp;C++&nbsp;写的话,或许就可以直接传物件的参考值了,而不光是传个指向函数的&nbsp;<BR>指标;自然地,物件会包含所有要用到的函数,甚至更多)。&nbsp;<BR>&nbsp;<BR>若想修改现有的软体,可拿最顶层的(非成员的)函数当作一层包装&nbsp;(wrapper),透&nbsp;<BR>过其他技巧(或许是放在全域变数中),把该物件包起来。这个最顶层的函数,会透&nbsp;<BR>过适当的成员函数去使用该全域变数。&nbsp;<BR>&nbsp;<BR>譬如,你想在中断处理中呼叫&nbsp;Fred::memfn()&nbsp;的话:&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;memfn();&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;staticmemfn();&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;用个&nbsp;static&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//wrapper&nbsp;函数会记得哪个物件该去启动全域物件的成员函数:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fred*&nbsp;object_which_will_handle_signal;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Fred_memfn_wrapper()&nbsp;{&nbsp;object_which_will_handle_signal-&gt;memfn();&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;/*&nbsp;signal(SIGINT,&nbsp;Fred::memfn);&nbsp;*/&nbsp;&nbsp;&nbsp;//不能这样做&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signal(SIGINT,&nbsp;Fred_memfn_wrapper);&nbsp;&nbsp;//Ok&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signal(SIGINT,&nbsp;Fred::staticmemfn);&nbsp;&nbsp;&nbsp;//Also&nbsp;Ok&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;<BR>注意:静态成员函数不需要真正的物件才能启动,所以指向静态成员函数的指标,和&nbsp;<BR>普通的指向函数的指标,具有相容的型态(详见&nbsp;ARM&nbsp;[&quot;Annotated&nbsp;Reference&nbsp;<BR>Manual&quot;]&nbsp;p.25,&nbsp;158)。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q113:当我想以成员函数做为中断服务常式&nbsp;(ISR)&nbsp;时,为什麽编译器产生(型态不&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;符)的错误?&nbsp;<BR>&nbsp;<BR>这是前两个问题的特例,所以请先看看前两则解答。&nbsp;<BR>&nbsp;<BR>非静态的成员函数,都有一个隐藏的参数,对应到&nbsp;'this'&nbsp;指标,该&nbsp;'this'&nbsp;指标会&nbsp;<BR>指向该物件的案例资料&nbsp;(instance&nbsp;data),可是系统中断的硬体/韧体并未提供这个&nbsp;<BR>'this'&nbsp;参数。你得用「正常的」函数(不是类别的成员)或是静态成员函数来做为&nbsp;<BR>中断服务常式才行。&nbsp;<BR>&nbsp;<BR>一个可行的解法是:用一个静态成员做为中断服务常式,让它能自己到某处去找案例&nbsp;<BR>/成员的配对,以供中断呼叫之用。这麽一来,当中断产生时,正常的&nbsp;method&nbsp;就会&nbsp;<BR>被启动,不过以技术观点来看,你得先呼叫一个中介函数。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q114:为什麽我取不出&nbsp;C++&nbsp;函数的位址?&nbsp;<BR>&nbsp;<BR>这可由前一则&nbsp;FAQ&nbsp;推论过来。&nbsp;<BR>&nbsp;<BR>详细的解答:在&nbsp;C++&nbsp;里,成员函数有一个隐含的参数,指向该物件本身(成员函数&nbsp;<BR>内的&nbsp;&quot;this&quot;&nbsp;指标)。正常的&nbsp;C&nbsp;函数与成员函数的呼叫惯例可视为不同,所以它们&nbsp;<BR>指标的型态(指向成员函数&nbsp;vs&nbsp;指向函数)既不同也不相容。C++&nbsp;引进一个新的指标&nbsp;<BR>型态:指向成员的指标,要提供一个物件才能启动之(见&nbsp;ARM&nbsp;[&quot;Annotated&nbsp;<BR>Reference&nbsp;Manual&quot;]&nbsp;5.5)。&nbsp;<BR>&nbsp;<BR>注意:不要去把指向成员函数的指标强制转型成指向函数的指标;这样做的结果是未&nbsp;<BR>定义的,且下场可能会很惨。譬如,指向成员函数的指标,“不必然”会包含某正常&nbsp;<BR>函数的机器位址(看&nbsp;ARM,&nbsp;8.1.2c,&nbsp;p.158)。如前例所提,如果你有个指向正常&nbsp;C&nbsp;<BR>函数的指标的话,请用上层的(非成员的)函数,或是用&nbsp;&quot;static&quot;&nbsp;成员函数(类别&nbsp;<BR>成员函数)。&nbsp;<BR>&nbsp;<BR>========================================&nbsp;<BR>&nbsp;<BR>Q115:怎样宣告指向成员函数的指标阵列?&nbsp;<BR>&nbsp;<BR>用&nbsp;&quot;typedef&quot;&nbsp;好让你的脑筋保持清醒。&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;int&nbsp;f(char&nbsp;x,&nbsp;float&nbsp;y);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;g(char&nbsp;x,&nbsp;float&nbsp;y);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;h(char&nbsp;x,&nbsp;float&nbsp;y);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i(char&nbsp;x,&nbsp;float&nbsp;y);&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;&nbsp;int&nbsp;(Fred::*FredPtr)(char&nbsp;x,&nbsp;float&nbsp;y);&nbsp;<BR>&nbsp;<BR>这是指向成员函数的指标阵列:Here's&nbsp;the&nbsp;array&nbsp;of&nbsp;pointers&nbsp;to&nbsp;member&nbsp;functions:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FredPtr&nbsp;a[4]&nbsp;=&nbsp;{&nbsp;&amp;Fred::f,&nbsp;&amp;Fred::g,&nbsp;&amp;Fred::h,&nbsp;&amp;Fred::i&nbsp;};&nbsp;<BR>&nbsp;<BR>呼叫物件&nbsp;&quot;fred&quot;&nbsp;的某一个成员函数:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;userCode(Fred&amp;&nbsp;fred,&nbsp;int&nbsp;methodNum,&nbsp;char&nbsp;x,&nbsp;float&nbsp;y)&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//假设&nbsp;&quot;methodNum&quot;&nbsp;在&nbsp;[0,3]&nbsp;区间内&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fred.*a[methodNum])(x,&nbsp;y);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;<BR>你可以用&nbsp;#define&nbsp;让这个呼叫清楚些:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#define&nbsp;&nbsp;callMethod(object,ptrToMethod)&nbsp;&nbsp;&nbsp;((object).*(ptrToMethod))&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;callMethod(fred,&nbsp;a[methodNum])&nbsp;(x,&nbsp;y);&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>====================================&nbsp;<BR>■□&nbsp;第19节:容器类别与&nbsp;template&nbsp;<BR>====================================&nbsp;<BR>&nbsp;<BR>Q116:怎样自一个连结串列/杂凑表等等里面,插入/存取/改变元素?&nbsp;<BR>&nbsp;<BR>我将以最简单的「插入连结串列」为例。想把元素插入串列的头尾很容易,但只限&nbsp;<BR>於这些功能的话,会使程式库过於低能(太低能的程式库比没有更糟)。&nbsp;<BR>&nbsp;<BR>完整的解答会让&nbsp;C++&nbsp;新手消化不良,所以我只提几个项目。第一个是最简单的,第&nbsp;<BR>二和第三是比较好的。&nbsp;<BR>&nbsp;<BR>[1]&nbsp;替&nbsp;&quot;List&quot;&nbsp;加入一个「现在位置」的性质,加入像是&nbsp;advance()、backup()、&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;atEnd()、atBegin()、getCurrElem()、setCurrElem(Elem)、insertElem(Elem)&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;、removeElem()&nbsp;等等的运作行为。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;即使在这个小例子里已经够用了,但「只有一个」现在位置的记号的话,想存取&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;串列中两个以上位置的元素就不太容易(譬如:「对所有&nbsp;x,y&nbsp;序对,做底下的&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;事情……」)。&nbsp;<BR>&nbsp;<BR>[2]&nbsp;把上述的&nbsp;List&nbsp;运作行为拿掉,移到独立的类别&nbsp;&quot;ListPosition&quot;&nbsp;中。&nbsp;<BR>

⌨️ 快捷键说明

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