C++语言常见问题解答(2)

2008-02-23 05:34:51来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

== Part 2/4  ============================ 

============================= 
■□ 第9节:自由记忆体管理 
============================= 
 
Q33:"delete p" 会删去 "p" 指标,还是他指到的资料,"*p" ? 
 
该指标指到的资料。 
 
"delete" 真正的意思是:「删去指标所指到的东西」(delete the thing pointed 
to by)。同样的英文误用也发生在 C 语言的「『释放』指标所指向的记忆体」上 
("free(p)" 真正的意思是:"free_the_stuff_pointed_to_by(p)" )。 
 
======================================== 
 
Q34:我能 "free()" 掉由 "new" 配置到的、"delete" 掉由 "malloc()" 配置到的 
      记忆体吗? 
 
不行。 
 
在同一个程式里,使用 malloc/free 及 new/delete 是完全合法、合理、安全的; 
但 free 掉由 new 配置到的,或 delete 掉由 malloc 配置到的指标则是不合法、 
不合理、该被痛骂一顿的。 
 
======================================== 
 
Q35:为什麽该用 "new" 而不是老字号的 malloc() ? 
 
建构子/解构子、型别安全性、可被覆盖(overridability)。 
 
建构子/解构子:和 "malloc(sizeof(Fred))" 不同,"new Fred()" 还会去呼叫 
Fred 的建构子。同理,"delete p" 会去呼叫 "*p" 的解构子。 
 
型别安全性:malloc() 会传回一个不具型别安全的 "void*",而 "new Fred()" 则 
会传回正确型态的指标(一个 "Fred*")。 
 
可被覆盖:"new" 是个可被物件类别覆盖的运算子,而 "malloc" 不是以「各个类别 
」作为覆盖的基准。 
 
======================================== 
 
Q36:为什麽 C  不替 "new" 及 "delete" 搭配个 "realloc()" ? 
 
避免您产生意外。 
 
当 realloc() 要拷贝配置区时,他做的是「逐位元 bitwise」的拷贝,这会弄坏大 
部份的 C  物件。但是 C  的物件应该要能自我拷贝才对:用他们自己的拷贝建构 
子或设定运算子。 
 
======================================== 
 
Q37:我该怎样配置/释放阵列? 
 
用 new[] 和 delete[] : 
 
         Fred* p = new Fred[100]; 
         //... 
         delete [] p; 
 
每当您在 "new" 运算式中用了 "[...]",您就必须在 "delete" 陈述中使用 "[]"。 
                                          ^^^^ 
这语法是必要的,因为「指向单一元素的指标」和「指向一个阵列的指标」在语法上 
并无法区分开来。 
 
======================================== 
 
Q38:万一我忘了将 "[]" 用在 "delete" 由 "new Fred[n]" 配置到的阵列,会发生 
      什麽事? 
 
灾难。 
 
这是程式者的--而不是编译器的--责任,去确保 new[] 和 delete[] 的正确配 
对。若您弄错了,编译器不会产生任何编译期或执行期的错误讯息。堆积(heap)被 
破坏是最可能的结局,或是更糟的,您的程式会当掉。 
 
======================================== 
 
Q39:成员函数做 "delete this" 的动作是合法的(并且是好的)吗? 
 
只要您小心的话就没事。 
 
我所谓的「小心」是: 
 
   1) 您得 100% 确定 "this" 是由 "new" 配置来的(而非 "new[]",亦非自订的 
      "new" 版本,一定要是最原始的 "new")。 
 
   2) 您得 100% 确定该成员函数是此物件最後一个会呼叫到的。 
 
   3) 做完自杀的动作 ("delete this;") 後,您不能再去碰 "this" 的物件了,包 
      括资料及运作行为在内。 
 
   4) 做完自杀的动作 ("delete this;") 後,您不能再去碰 "this" 指标了。 
      换句话说,您不能查看他、将他和其他指标或是 NULL 相比较、印出其值、 
      对他转型、对他做任何事情。 
 
很自然的,这项警告也适用於:当 "this" 是个指向基底类别的指标,而解构子不是 
virtual 的场合。 
 
======================================== 
 
Q40:我该怎麽用 new 来配置多维阵列? 
 
有很多方法,端视您对阵列大小的伸缩性之需要而定。极端一点的情形,假如您在编 
译期就知道任何阵列的维度,您能够静态地配置(就像 C 相同): 
 
         class Fred { /*...*/ }; 
 
         void manipulateArray() 
         { 
           Fred matrix[10][20]; 
 
           //使用 matrix[i][j]... 
 
           //不须特地去释放该阵列 
         } 
 
另一个极端情况,假如您希望该矩阵的每个小块都能不相同大,您能够在自由记忆体 
里配置之: 
 
         void manipulateArray(unsigned nrows, unsigned ncols[]) 
         //'nrows' 是该阵列之列数。 
         //所以合法的列数为 (0, nrows-1) 开区间。 
         //'ncols[r]' 则是 'r' 列的行数 ('r' 值域为 [0..nrows-1])。 
         { 
           Fred** matrix = new Fred*[nrows]; 
           for (unsigned r = 0; r < nrows;  r) 
             matrix[r] = new Fred[ ncols[r] ]; 
 
           //使用 matrix[i][j]... 
 
           //释放就是配置的反动作: 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C++语言常见问题解答(1)A

下一篇: C++语言常见问题解答(3)