C++語言常見問題解:#121 ~ #140

這是我從臺灣的http://www.cis.nctu.edu.tw/chinese/doc/research/c++/C++FAQ-Chinese/發現的《C++ Frequently Asked Questions》的繁體翻譯,作者是:葉秉哲,也是《C++ Programming Language》3/e繁體版的譯者,該文章是非常的好,出於學習用途而將它轉貼,本人未取得作者的授權,原文章的版權仍然歸屬原作者.

C++語言常見問題解
Q121:「泛型」(genericity)是什麼?

另一種 "class template" 的說法。

不要和「一般化」(generality,指不要過於特定的解題)弄混了,「泛型」指的是
class template。


=======================
■□ 第20節:鏈接庫
=======================

Q122:怎樣拿到 "STL"?

"STL" 代表 "Standard Templates Library",標準模版鏈接庫。取得法:

STL HP official site:
ftp://butler.hpl.hp.com/stl
STL code alternate: ftp://ftp.cs.rpi.edu/stl
STL code + examples: http://www.cs.rpi.edu/~musser/stl.html

STL hacks for GCC-2.6.3 已經在 GNU libg++ 2.6.2.1 或更新版本里了(可能較早
的版本也有)。多謝 Mike Lindner。

========================================

Q123:怎樣 ftp 到 "Numerical Recipes" 附的程序?

它是用賣的,把它放到網絡上散佈是違法的。不過它只需 $30 美元而已。

========================================

Q124:爲什麼我的執行檔會這麼大?

很多人對這麼大的執行檔感到驚訝,特別是當原始碼只有一點點而已。例如一個簡單
的 "hello world" 程序居然會產生大家都想不到的大小(40+K bytes)。

一個原因是:有些 C++ 執行期鏈接庫被連結進去了。有多少被連結進去,就要看看
你用到多少,以及編譯器把鏈接庫切割成多少塊而定。例如,iostream 很大,包含
一大堆類別及虛擬函數,即使你只用到一點點,因爲各組件之間的交互參考依存關係
,可能會把整個 iostream 程序代碼都塞進來了。(【譯註】如果 linker 做得好的話
,應該能把完全用不到的組件 object code 砍掉,不隨之塞入你的執行檔中。)

不要用靜態的,改用動態連結的鏈接庫版本,就可以使你的程序變小。

欲知詳情,請看看你的編譯器手冊,或是尋求廠商的技術支持。


===============================
■□ 第21節:特定系統的細節
===============================

Q125:GNU C++ (g++) 把小程序造出大大的執行檔,爲什麼?

libg++(g++ 用到的鏈接庫)可能在編譯時帶有除錯的信息(-g)。有些機器上,不
帶除錯信息地重新編譯它,會省下很大的磁盤空間(~1 MB;缺點是:不能追蹤到
libg++ 的呼叫)。僅僅 "strip" 掉執行檔,比不上先用 -g 重新編譯,再 "strip"
掉 a.out 檔來得有效。

用 "size a.out" 來看看執行碼的程序與資料區段到底佔了多大空間,而不要用
"ls -s a.out" 這種包括了符號表格(symbol table)的方式。

========================================

Q126:有 YACC 的 C++ 文法嗎?

Jim Roskind 是 C++ 的 YACC 文法作者,它大體上和部份 USL cfront 2.0 所實作
出來的語言兼容(沒有 template、例外、執行期型態識別功能)。這份文法有些地
方和 C++有細小而微妙的差別。

它可用 anonymous ftp 到下列地方取得:
* ics.uci.edu (128.195.1.1) in "gnu/c++grammar2.0.tar.Z".
* mach1.npac.syr.edu (128.230.7.14) in "pub/C++/c++grammar2.0.tar.Z".

========================================

Q127:什麼是 C++ 1.2? 2.0? 2.1? 3.0?

這些不是“語言”的版本,而是 cfront 這個由 AT&T 做出來的、最早的 C++轉譯程
式的版本編號。以這編號來“代表”C++ 語言的演進,已經是公認的慣例了。

“非常”粗略地講,主要的特徵有:
* 2.0 包含多重/虛擬繼承,以及純虛擬函數。
* 2.1 包含半巢狀 (semi-nested) 類別,及 "delete [] 數組指針"。
* 3.0 包含全巢狀 (fully-nested) 類別、template 和 "i++" vs "++i"。
* 4.0 將包含例外處理。

========================================

Q128:如果簽名編碼標準化了,我能否將不同廠商編譯器產生的程序代碼連結起來?

簡短的回答:可能不行。

換句話說,有人希望標準化的簽名編碼規則能併入擬議中的 C++ ANSI 標準,避免還
要爲不同廠商的編譯器購買不同版本的對象鏈接庫。然而不同的系統實作中,簽名編
碼的差異性只佔一小部份而已,即使是在同一個基臺(platform)上。這裏列出一部
份其它的差異處:

1) 成員函數隱含的自變量個數和型態。
1a) 'this' 有被特殊處理嗎?
1b) 傳值的指針放在哪裏?
2) 假設有用到 vtable 虛擬表格的話:
2a) 它的內容及配置?
2b) 多重繼承時,'this' 在何處/如何調整?
3) 類別如何配置,包含:
3a) 基底類別的位置?
3b) 虛擬基底類別的處理?
3c) 虛擬表格指針的位置,如果有用虛擬表格的話?
4) 函數的呼叫慣例,包含:
4a) 呼叫者還是被呼叫者負責調整堆棧?
4b) 實際參數放到哪裏?
4c) 實際參數傳遞之順序?
4d) 緩存器如何存放?
4e) 傳回值放到哪裏?
4f) 對傳入/傳回 struct 或 double 有無特殊的規定?
4g) 呼叫末端函數(leaf function)有無特殊的緩存器存放規定?
5) run-time-type-identification 如何配置?
6) 當一個例外被 throw 時,執行期的例外處理系統如何得知哪一個區域對象該被解
構?


=======================================
■□ 第22節:其它的技術和環境的事項
=======================================
● 22A:其它的技術事項
========================

Q129:爲什麼有 static 資料成員的對象類別產生了 linker 錯誤?

Static 的數據成員必須外顯地在唯一的模塊中定義。
^^^^^^ ~~~~~~^^^^ ^^^^
【譯註】這句話要逐字細讀。原文是:Static data members must be
explicitly defined in exactly one module.

譬如:
class Fred {
public:
  //...
private:
static int i_; // 宣告 static 資料成員 "Fred::i_"
//...
};

Linker 會告訴你 "Fred::i_ is not defined(未定義)" ,除非你在任何一個(且
唯一)原始檔中定義(而非宣告)了 "Fred::i_" :

int Fred::i_ = 某個會產生 int 的表達式;
或是:
int Fred::i_;

通常我們會在 "Fred.C" 檔中定義 "Fred" 類別的 static 資料成員(或 "Fred.cpp"
等等你使用的擴展名)。

========================================

Q130:"struct" 和 "class" 關鍵詞差別在哪?

struct 的成員和基底類別, 都是預設爲 public 的,而 class 則預設爲 private。
注意:你應該“明顯地”把基底類別設爲 public、private 或是 protected,而不
要依賴默認值。

除此之外,兩者的功能是相等的。

========================================

Q131:爲什麼不能以函數的傳回值來多載(overload)它?

如果你同時宣告了 "char f()" 及 "float f()" ,編譯器會給你個錯誤訊息,因爲
呼叫 "f()" 會造成仿真兩可的情況。

========================================

Q132:什麼是「持續性」?什麼是「持續性對象」?

一個持續性對象 (persistent object),在創造它的程序執行結束後,仍可存活下來
。它甚至可存活於不同的父程序,存活於磁盤系統、操作系統、甚至於操作系統所處
的硬件上。

持續性對象的困難在於:如何有效地在次儲存體中,存放它們的運作行爲(method)
及資料位(以及所有成員對象的資料和運作行爲,及它們所有的成員對象、基底類
別……等等)。這一切都得自己來做的話,可不是件容易的事。在 C++中,你就得自
己來。C++/OO 的數據庫系統,會替你把這些機制都隱藏起來。

========================================

Q133:爲什麼浮點數 (floating point) 這麼不精確?爲什麼這段程序不會印出 0.43?

#include<iostream.h>

main()
{
float a = 1000.43;
float a = 1000.0;
cout << a - b << '/n';
}

(附註,有些 C++ 環境下會印出 0.429993)

聲明:受進位/舍位/近似值之苦,其實並不是 C++ 的問題,而是計算機科學界的問
題。不過還是一直有人在 comp.lang.c++ 裏發問,所以我給你一個答案意思一下。

答案:浮點數本來就是個近似值。在 IEEE 的 32 位浮點數標準裏,有 1 位的
正負號,8 位的指數,23 位的假數。因爲正規化後的二進制假數都會變成像是
1.xxxxx... 的型式,所以頭一項的 1 不予計入,就能得到 24 位的有效假數。
1000.43(以及其它很多很多數字)都不是 float 或 double 的表示法,其實
1000.43 的位內容是這樣子的('s' 代表正負號,'e' 代表指數,'m' 代表假數)


seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
01000100011110100001101110000101

假數移位後變成 1111101000.01101110000101 或是 1000 + 7045/16384。
分數部份爲 0.429992675781。
float 的假數佔 24 位,所以你只得到 16M 分之一的精確度。
double 有較高的精確度(53 位的假數)。

==========================
● 22B:其它環境下的瑣事
==========================

Q134:有任何 TeX 或 LaTeX 的宏,能處理 "C++" 的留白效果(spacing)嗎?

有的,底下列出兩個:

/def/CC{C/raise.22ex/hbox{{/footnotesize +}}/raise.22ex/hbox{/footnotesize +}}

/def/CC{{C/hspace{-.05em}/raisebox{.4ex}{/tiny/bf ++}}}

========================================

Q135:在哪兒可拿到 C++2LaTeX 這個 C++原始碼的 LaTeX 美編工具(pretty
printer)?

這兒列出一些 ftp 地點:

Host aix370.rrz.uni-koeln.de (134.95.80.1) Last updated 15:41 26 Apr 1991
Location: /tex
 FILE rw-rw-r-- 59855 May 5 1990 C++2LaTeX-1.1.tar.Z
Host utsun.s.u-tokyo.ac.jp (133.11.11.11) Last updated 05:06 20 Apr 1991
Location: /TeX/macros
FILE rw-r--r-- 59855 Mar 4 08:16 C++2LaTeX-1.1.tar.Z
Host nuri.inria.fr (128.93.1.26) Last updated 05:23 9 Apr 1991
Location: /TeX/tools
FILE rw-rw-r-- 59855 Oct 23 16:05 C++2LaTeX-1.1.tar.Z
Host iamsun.unibe.ch (130.92.64.10) Last updated 05:06 4 Apr 1991
Location: /TeX
FILE rw-r--r-- 59855 Apr 25 1990 C++2LaTeX-1.1.tar.Z
Host iamsun.unibe.ch (130.92.64.10) Last updated 05:06 4 Apr 1991
Location: /TeX
FILE rw-r--r-- 51737 Apr 30 1990
C++2LaTeX-1.1-PL1.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9)
Last updated 05:07 18 Apr 1991
Location: /pub/textproc/TeX
FILE rw-r--r-- 72957 Oct 25 13:51 C++2LaTeX-1.1-PL4.tar.Z
Host wuarchive.wustl.edu (128.252.135.4) Last updated 23:25 30 Apr 1991
Location: /packages/tex/tex/192.35.229.9/textproc/TeX
FILE rw-rw-r-- 49104 Apr 10 1990 C++2LaTeX-PL2.tar.Z
FILE  rw-rw-r-- 25835 Apr 10 1990 C++2LaTeX.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9)
Last updated 05:07 18 Apr 1991
Location: /pub/textproc/TeX
FILE rw-r--r-- 74015 Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
Location: /pub
   FILE rw-r--r-- 74015 Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
Host sol.cs.ruu.nl (131.211.80.5) Last updated 05:10 15 Apr 1991
Location: /TEX/TOOLS
FILE rw-r--r-- 74015 Apr 4 21:02x C++2LaTeX-1.1-PL5.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9)
Last updated 05:07 18 Apr 1991
Location: /pub/textproc/TeX
FILE rw-r--r--    4792 Sep 11 1990 C++2LaTeX-1.1-patch#1
FILE rw-r--r-- 2385 Sep 11 1990 C++2LaTeX-1.1-patch#2
FILE rw-r--r-- 5069 Sep 11 1990 C++2LaTeX-1.1-patch#3
FILE rw-r--r-- 1587 Oct 25 13:58 C++2LaTeX-1.1-patch#4
FILE rw-r--r-- 8869 Mar 22 16:23 C++2LaTeX-1.1-patch#5
FILE rw-r--r-- 1869 Mar 22 16:23 C++2LaTeX.README
Host rusmv1.rus.uni-stuttgart.de (129.69.1.12)
Last updated 05:13 13 Apr 1991
Location: /soft/tex/utilities
FILE rw-rw-r-- 163840 Jul 16 1990 C++2LaTeX-1.1.tar

========================================

Q136:該到哪裏取得 "tgrind" 這個 C++/C/etc 的原始碼美編工具?

"tgrind" 讀入 C++ 源文件,並輸出能讓 Unix 打印機印出美觀文件的東西。它常
會伴隨在 TeX 和 LaTeX 的套件裏;請找找這個目錄:
"...tex82/contrib/van/tgrind" 。 由 Jerry Leichter 所做更新的版本,可在
venus.ycc.yale.edu in [.TGRIND] 裏找到。

========================================

Q137:有給 GNU emacs 編輯器用的 C++-mode 嗎?有的話,該怎麼拿?

Yes,有一個給 GNU emacs 用的 C++-mode。

最新﹑最好的 C++-mode(以及 c-mode)版本是 cc-mode.el 檔,是 Detlef &
Clamen 版本的延伸。Emacs 裏頭有一個了,較新的則在 elisp 裏面。

========================================

Q138:我要到哪兒得到和操作系統相關的 FAQs( 譬如:BC++﹑DOS﹑Windows 等等
)?

請參考:
* comp.os.msdos.programmer
* comp.windows.ms.programmer
* comp.unix.programmer

[如果您有 BC++、VC++ 的 email address,或是 Semantic C++ 的臭蟲清單或可供
討論的 mailing list,請告訴我該如何加入,我會在這兒提出的。]

========================================

Q139:爲什麼我的 DOS C++ 程序說 "Sorry: floating point code not linked"
“抱歉,浮點運算程序代碼未連結進來”?

編譯器會試着節省執行檔的大小,所以除非必要,否則不引入浮點數→字符串格式轉換
的子程序,可是有時候它會猜錯,就會產生上述的錯誤訊息了。解決法:(1) 使用
<iostream.h> 而不要用 <stdio.h>,或是 (2) 在您程序的某個地方,置入如下的函
數(但是不要真的去呼叫它!):

static void dummyfloat(float *x) { float y; dummyfloat(&y); }

請參考關於 stream I/O 的 FAQ項目,有提到更多使用 <iostream.h> vs <stdio.h>
的理由。

========================================

Q140:爲什麼當我沒執行 BC45 IDE 的話,BC++ 做出來的 Windows 應用程序就不能
用?

用 BC++ 寫 Windows 應用程序,如果當 BC45 IDE 正在執行時,你的程序很正常;
待會兒當 BC45 IDE 關掉了,而你的程序卻在建立窗口時產生了個 exception 的話
,就把底下這行程序加到你的應用程序類別 ("YourApp::InitMainWindow()") 裏頭
的 InitMainWindow() 內:

EnableBWCC(TRUE);

【譯註】這是因爲你用 BC++ 寫的應用程序,可能會自動用到 bwcc*.dll,剛好
BC++ 的 IDE 也會用到它,所以兩者並存的話,BWCC 已先被 IDE 加載了。
若是 IDE 未執行,則 BWCC 未被加載,你就得用上面那一行程序來通知
OWL 去加載它。

== comp.lang.c++ FAQ 結束 =========================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章