| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6322 人关注过本帖
标题:推荐:C++语言常见问题解答
只看楼主 加入收藏
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
怎样自一个连结串列/杂凑表等等里面,插入/存取/改变元素? 
 
我将以最简单的「插入连结串列」为例。想把元素插入串列的头尾很容易,但只限 
於这些功能的话,会使程式库过於低能(太低能的程式库比没有更糟)。 
 
完整的解答会让 C++ 新手消化不良,所以我只提几个项目。第一个是最简单的,第 
二和第三是比较好的。 
 
[1] 替 "List" 加入一个「现在位置」的性质,加入像是 advance()、backup()、 
     atEnd()、atBegin()、getCurrElem()、setCurrElem(Elem)、insertElem(Elem) 
     、removeElem() 等等的运作行为。 
 
     即使在这个小例子里已经够用了,但「只有一个」现在位置的记号的话,想存取 
     串列中两个以上位置的元素就不太容易(譬如:「对所有 x,y 序对,做底下的 
     事情……」)。 
 
[2] 把上述的 List 运作行为拿掉,移到独立的类别 "ListPosition" 中。 
 
     ListPosition 的作用是:代表 List 里「现在的位置」,这样就允许许多位置 
     并存於同一个串列中。ListPosition 是 List 的夥伴,所以 List 的内部可对 
     外界隐藏起来(否则 List 的内部就会被它的公共运作行为所公开)。注意: 
     ListPosition 可以把运算子多载起来,像是 advance()、backup(),因为运算 
     子多载只是正常运作行为的语法糖衣而已。 
 
[3] 把整个位置处理(iteration)当成是一个基元事件(atomic event),建一个 
     class template 去涵盖该事件。 
 
     它不会在内部回圈中使用公共存取运作行为(它有可能是虚拟函数),所以效率 
     能增进。不幸的,你的应用软体会多出些额外的二元码,因为 template 是以空 
     间换取时间的。欲知详情,请见 [Koenig, "Templates as interfaces," 
     JOOP, 4, 5 (Sept 91)], 以及 [Stroustrup, "The C++ Programming Language 
     Second Edition," under "Comparator"]. 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:52
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
「样版」(template)的用意是什麽? 
 
Template 本意是个压饼模子,它把饼乾都压成差不多一个样子(虽然饼乾的原料不 
尽相同,但它们都有相同的基本外形)。同理,class template 是个样版模子,用 
来描述如何将一系列的物件类别弄成同一个基本型式;而 function template 则是 
用以描述一系列看起来差不多的函数。 
 
Class template 常用於制造型别安全的容器(即使这仅止於「如何使用它」而已)。 
 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:52
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
"function template" 的语法/语意是什麽? 
 
考虑底下这个交换两个整数引数的函数: 
 
         void swap(int& x, int& y) 
         { 
           int tmp = x; 
           x = y; 
           y = tmp; 
         } 
 
假如我们想交换 float、long、String、Set 和 FileSystems,我们还得写那些 
大致看起来都一样、只有型态不同的程式码,有够烦人。这种不花脑筋的重复性工作 
,正是电脑的专长,於是我们想出了 function template: 
 
         template 
         void swap(T& x, T& y) 
         { 
           T tmp = x; 
           x = y; 
           y = tmp; 
         } 
 
每次我们以一组型别来使用 "swap()",编译器会找到上面这定义,并造出另一个 
"template function" ,来当作它的「案例」(instantiation)。譬如: 
 
         main() 
         { 
           int    i,j;  /*...*/  swap(i,j);  // 案例化 "int"    的 swap 
           float  a,b;  /*...*/  swap(a,b);  // 案例化 "float"  的 swap 
           char   c,d;  /*...*/  swap(c,d);  // 案例化 "char"   的 swap 
           String s,t;  /*...*/  swap(s,t);  // 案例化 "String" 的 swap 
         } 
 
(注意:"template function" 是 "function template" 实体化之後的案例。) 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:52
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
"class template" 的语法/语意是什麽? 
 
考虑像是个整数阵列的容器类别: 
 
         // 这会放在像是 "Array.h" 的标头档中 
         class Array { 
         public: 
           Array(int len=10)                  : len_(len), data_(new int[len]){} 
          ~Array()                            { delete [] data_; } 
           int len() const                    { return len_;     } 
           const int& operator[](int i) const { data_[check(i)]; } 
                 int& operator[](int i)       { data_[check(i)]; } 
           Array(const Array&); 
           Array& operator= (const Array&); 
         private: 
           int  len_; 
           int* data_; 
           int  check(int i) const 
             { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_); 
               return i; } 
         }; 
 
如同前述的 "swap()" ,一再为 float、char、String、Array-of-String 等等来重 
复设计 Array 类别,是很烦人的。 
 
         // 这会放在像是 "Array.h" 的标头档中 
         template 
         class Array { 
         public: 
           Array(int len=10)                : len_(len), data_(new T[len]) { } 
          ~Array()                          { delete [] data_; } 
           int len() const                  { return len_;     } 
           const T& operator[](int i) const { data_[check(i)]; } 
                 T& operator[](int i)       { data_[check(i)]; } 
           Array(const Array&); 
           Array& operator= (const Array&); 
         private: 
           int len_; 
           T*  data_; 
           int check(int i) const 
             { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_); 
               return i; } 
         }; 
 
不像 template function 那样,template classes(案例化的 class template)必 
须将那些用来案例化的参数型态明示出来: 
 
         main() 
         { 
           Array           ai; 
           Array         af; 
           Array         ac; 
           Array        as; 
           Array< Array >  aai; 
         }              // ^^^-- 注意这空格;不要用 "Array>" 
                        //       (编译器会把 ">>" 看成单一的元素) 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:52
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
什麽是「参数化型别」(parameterized type)? 
 
另一种 "class template" 的说法。 
 
「参数化型别」是一种型别,它被另一个型别或数值所参数化(parameterized)了。 
像 List 是一个型别 ("List") ,它被另一个型别 ("int") 所参数化。 
 
======================================== 
 
Q121:「泛型」(genericity)是什麽? 
 
另一种 "class template" 的说法。 
 
不要和「一般化」(generality,指不要过於特定的解题)弄混了,「泛型」指的是 
class template。 
 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:53
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
怎样拿到 "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。 
 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:53
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
怎样 ftp 到 "Numerical Recipes" 附的程式? 
 
它是用卖的,把它放到网路上散布是违法的。不过它只需 $30 美元而已。 
 
======================================== 
 
Q124:为什麽我的执行档会这麽大? 
 
很多人对这麽大的执行档感到惊讶,特别是当原始码只有一点点而已。例如一个简单 
的 "hello world" 程式居然会产生大家都想不到的大小(40+K bytes)。 
 
一个原因是:有些 C++ 执行期程式库被连结进去了。有多少被连结进去,就要看看 
你用到多少,以及编译器把程式库切割成多少块而定。例如,iostream 很大,包含 
一大堆类别及虚拟函数,即使你只用到一点点,因为各元件之间的交互参考依存关系 
,可能会把整个 iostream 程式码都塞进来了。(【译注】如果 linker 做得好的话 
,应该能把完全用不到的元件 object code 砍掉,不随之塞入你的执行档中。) 
 
不要用静态的,改用动态连结的程式库版本,就可以使你的程式变小。 
 
欲知详情,请看看你的编译器手册,或是寻求厂商的技术支援。 
 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:53
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
GNU C++ (g++) 把小程式造出大大的执行档,为什麽? 
 
libg++(g++ 用到的程式库)可能在编译时带有除错的资讯(-g)。有些机器上,不 
带除错资讯地重新编译它,会省下很大的磁碟空间(~1 MB;缺点是:不能追踪到 
libg++ 的呼叫)。仅仅 "strip" 掉执行档,比不上先用 -g 重新编译,再 "strip" 
掉 a.out 档来得有效。 
 
用 "size a.out" 来看看执行码的程式与资料区段到底占了多大空间,而不要用 
"ls -s a.out" 这种包括了符号表格(symbol table)的方式。 
 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:53
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
有 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". 

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:53
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
什麽是 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 将包含例外处理

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2006-12-23 22:53
快速回复:推荐:C++语言常见问题解答
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023339 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved