| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6325 人关注过本帖
标题:推荐:C++语言常见问题解答
只看楼主 加入收藏
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
怎样处理建构子的错误? 
 
丢出一个例外(throw an exception)。 
 
建构子没有传回值,所以不可能采用它传回的错误码。因此,侦测建构子错误最好的 
方法,就是丢出一个例外。 
 
在 C++ 编译器尚未提供例外处理之前,我们可先把物件置於「半熟」的状态(譬如 
:设个内部的状态位元),用个查询子("inspector")来检查该位元,就可让用户 
查看该物件是否还活著。也可以用另一个成员函数来检查该位元,若该物件没存活 
下来,就做个「没动作」(或是更狠的像是 "abort()" )的程式。但这实在很丑陋。 

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:33
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
如果建构子会丢出例外的话,该怎麽处理它的资源? 
 
物件里面的每个资料成员,都该自己收拾残局。 
 
如果建构子丢出一个例外的话,该物件的解构子就“不会”执行。如果你的物件得回 
复些曾做过的事情(像是配置记忆体、开启档案、锁定 semaphore),该物件内的资 
料成员就“必须”记住这个「必须恢复的东西」。 
 
举例来说:不要单单的把配置到的记忆体放入 "Fred*" 资料成员,而要放入一个「 
聪明的指标」(smart pointer) 资料成员中;当该“聪明指标”死掉的话,它的解构 
子就会删去 Fred 物件

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:33
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
什麽是 "const correctness"? 
 
好问题。 
 
「常数正确性」乃使用 "const" 关键字,以确保常数物件不会被更动到。譬如:若 
"f()" 函数接收一个 "String",且 "f()" 想确保 "String" 不会被改变,你可以: 
 
  * 传值呼叫 (pass by value):    void  f(      String  s   )  { /*...*/ } 
  * 透过常数参考 (reference):    void  f(const String& s   )  { /*...*/ } 
  * 透过常数指标 (pointer)  :    void  f(const String* sptr)  { /*...*/ } 
  * 但不能用非常数参考      :    void  f(      String& s   )  { /*...*/ } 
  * 也不能用非常数指标      :    void  f(      String* sptr)  { /*...*/ } 
 
在接收 "const String&" 参数的函数里面,想更动到 "s" 的话,会产生个编译期的 
错误;没有牺牲任何执行期的空间及速度。 
 
宣告 "const" 参数也是另一种型别安全方法,就像一个常数字串,它会“丧失”各 
种可能会变更其内容的行为动作。如果你发现型别安全性质让你的系统正确地运作 
(这是真的;特别是大型的系统),你会发现「常数正确性」亦如是。

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:34
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
我该早一点还是晚一点让东西有常数正确性? 
 
越越越早越好。 
 
延後补以常数正确性,会导致雪球效应:每次你在「这儿」用了 "const",你就得在 
「那儿」加上四个以上的 "const"。 

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:34
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
什麽是「const 成员函数」? 
 
一个只检测(而不更动)其物件的成员函数。 
 
         class Fred { 
         public: 
           void f() const; 
         };      // ^^^^^--- 暗示说 "fred.f()" 不会改变到 "fred" 
 
此乃意指:「抽象层次」的(用户可见的)物件状态不被改变(而不是许诺:该物件 
的「每一个位元内容」都不会被动到)。C++ 编译器不会对你许诺「每一个位元」这 
种事情,因为不是常数的别名(alias)就可能会修改物件的状态(把 "const" 指标 
黏上某个物件,并不能担保该物件不被改变;它只能担保该物件不会「被该指标的动 
作」所改变)。 
 
【译注】请逐字细读上面这句话。 
 
"const" 成员函数常被称作「查询子」(inspector),不是 "const" 的成员函数则 
称为「更动子」(mutator)。 
 

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:34
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
若我想在 "const" 成员函数内更新一个「看不见的」资料成员,该怎麽做? 
 
使用 "mutable" 或是 "const_cast"。 
【译注】这是很新的 ANSI C++ RTTI (RunTime Type Information) 规定,Borland 
         C++ 4.0 就率先提供了 const_cast 运算子。 
 
少数的查询子需要对资料成员做些无害的改变(譬如:"Set" 物件可能想快取它上一 
回所查到的东西,以加速下一次的查询)。此改变「无害」是指:此改变不会由物件 
的外部介面察觉出来(否则,该运作行为就该叫做更动子,而非查询子了)。 
 
这类情况下,会被更动的资料成员就该被标示成 "mutable"(把 "mutable" 关键字 
放在该资料成员宣告处前面;也就是和你放 "const" 一样的地方),这会告诉编译 
器:此资料成员允许 const 成员函数改变之。若你不能用 "mutable" 的话,可以用 
"const_cast" 把 "this" 的「常数性」给转型掉。譬如,在 "Set::lookup() const" 
里,你可以说: 
 
         Set* self = const_cast(this); 
 
这行执行之後,"self" 的位元内容就和 "this" 一样(譬如:"self==this"),但 
是 "self" 是一个 "Set*" 而非 "const Set*" 了,所以你就可以用 "self" 去修改 
"this" 指标所指向的物件。 

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:35
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
"const_cast" 会不会丧失最佳化的可能? 
 
理论上,是;实际上,否。 
 
就算编译器没真正做好 "const_cast",欲避免 "const" 成员函数被呼叫时,会造成 
暂存器快取区被清空的唯一方法,乃确保没有任何「非常数」的指标指向该物件。这 
种情况很难得会发生(当物件在 const 成员函数被启用的□围内被建立出来;当所 
有非 const 的成员函数在物件建立间启用,和 const 成员函数的启用被静态系结住 
;当所有的启用也都是 "inline";当建构子本身就是 "inline";和当建构子所呼叫 
的任何成员函数都是 inline 时)。 
 
【译注】这一段话很难翻得好(好啦好啦!我功力不足... :-< ),所以附上原文: 
Even if a compiler outlawed "const_cast", the only way to avoid flushing 
the register cache across a "const" member function call would be to 
ensure that there are no non-const pointers that alias the object.  This 
can only happen in rare cases (when the object is constructed in the scope 
of the const member fn invocation, and when all the non-const member 
function invocations between the object's construction and the const 
member fn invocation are statically bound, and when every one of these 
invocations is also "inline"d, and when the constructor itself is "inline"d, 
and when any member fns the constructor calls are inline). 
 

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:35
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
「继承」对 C++ 来说很重要吗? 
 
是的。 
 
「继承」是抽象化资料型态(abstract data type, ADT)与 OOP 的一大分野。 

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:35
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
何时该用继承? 
 
做为一个「特异化」(specialization) 的机制。 
 
人类以两种角度来抽象化事物:「部份」(part-of) 和「种类」(kind-of)。福特汽 
车“是一种”(is-a-kind-of-a) 车子,福特汽车“有”(has-a) 引擎、轮胎……等 
等零件。「部份」的层次随著 ADT 的流行,已成为软体系统的一份子了;而「继承 
」则添入了“另一个”重要的软体分解角度

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:35
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 
怎样在 C++ 中表现出继承? 
 
用 ": public" 语法: 
 
         class Car : public Vehicle { 
                 //^^^^^^^^---- ": public" 读作「是一种」("is-a-kind-of-a") 
           //... 
         }; 
 
我们以几种方式来描述上面的关系: 
 
  * Car 是「一种」("a kind of a") Vehicle 
  * Car 乃「衍生自」("derived from") Vehicle 
  * Car 是个「特异化的」("a specialized") Vehicle 
  * Car 是 Vehicle 的「子类别」("subclass") 
  * Vehicle 是 Car 的「基底类别」("base class") 
  * Vehicle 是 Car 的「父类别」("superclass") (这不是 C++ 界常用的说法) 
    【译注】"superclass" 是 Smalltalk 语言的关键字。 
 

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:36
快速回复:推荐:C++语言常见问题解答
数据加载中...
 
   



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

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