《C++编程风格(修订版)》——2.5 动态内存的一致性
本節(jié)書摘來自異步社區(qū)出版社《C++編程風(fēng)格(修訂版)》一書中的第2章,第2.5節(jié),作者:【美】Tom Cargill,更多章節(jié)內(nèi)容可以訪問云棲社區(qū)“異步社區(qū)”公眾號查看。
2.5 動態(tài)內(nèi)存的一致性
C++編程風(fēng)格(修訂版)
在程序清單 2.2 的 string 類中仍然存在著一些問題和不一致的地方。其中,在動態(tài)內(nèi)存管理 上的不一致性與我們在前面所看到的不一致性是一樣的,都是嚴(yán)重的問題。對于所有動態(tài)分配的 內(nèi)存,我們都需要回答兩個問題:首先,動態(tài)內(nèi)存是不是足夠大以容納將要存儲的信息?其次, 是不是所有的動態(tài)內(nèi)存都是可回收的?
在默認(rèn)構(gòu)造函數(shù)中分配的字符數(shù)組肯定可以容納空字符串:
這個構(gòu)造函數(shù)所基于的假設(shè)是:在創(chuàng)建對象時將會為字符串分配內(nèi)存,并且這個內(nèi)存足以 容納在對象生存期內(nèi)需要保存的任意字符串。成員函數(shù) assign() 與這個假設(shè)也是一致的:
在 assign() 中調(diào)用 strcpy() 對參數(shù)字符串進行拷貝時,并沒有考慮到目標(biāo)字符數(shù)組的長度或 者大小。編寫客戶代碼的程序員必須保證——在創(chuàng)建對象時,無論調(diào)用的是哪個構(gòu)造函數(shù)——在 構(gòu)造函數(shù)中所創(chuàng)建的數(shù)組必須能夠容納在 assign() 中復(fù)制的任意字符串。
然而,在成員函數(shù) concat() 中采用了一種不同的方法:在創(chuàng)建每個字符串時,總是動態(tài)地決 定所需數(shù)組的精確大小。函數(shù) concat() 忽略了在創(chuàng)建 string 對象時已經(jīng)分配好的字符數(shù)組,即使 這個已分配的數(shù)組是足夠大的:
在 assign() 和 concat() 這兩個函數(shù)的表現(xiàn)行為上存在著不一致性。它們的區(qū)別在于,在為 string
對象設(shè)置新值時,是否會動態(tài)分配字符數(shù)組:assing() 永遠不會分配,而 concat() 則總是會分配。
接口一致性
上面哪種控制數(shù)組大小的方法是更好的?和許多軟件決策一樣,沒有哪種方法是絕對的“正 確”或者絕對的“錯誤”。這兩種方法都有各自的優(yōu)點。保持在構(gòu)造函數(shù)中分配的數(shù)組不變(assign() 中的做法)是一種高效的方法,因為在后續(xù)的操作中就無需再調(diào)用內(nèi)存分配函數(shù)。對每個字符串 值都動態(tài)地決定數(shù)組的大小(concat() 中的做法)則是一種更安全的方法,因為這種方法杜絕了 數(shù)組的“越界”行為。
這兩種方法都可以用在類中,但我們只能使用其中的一種,以保持類一致性,而不應(yīng)該將 這兩種方法混合使用。否則,在使用這個類時,程序員將不得不去了解在接口中不同操作之間的 不同約定。如果一個程序員只使用過 concat(),并且知道了數(shù)組的大小是動態(tài)增長的,那么他就 會假定 assign() 也是同樣的行為,因此,當(dāng)在 assign() 中發(fā)生數(shù)組內(nèi)存的越界問題時,他所感到 的沮喪應(yīng)該是可以預(yù)見的。
類的接口定義應(yīng)該是一致的——避免產(chǎn)生困惑。
總結(jié)
以上是生活随笔為你收集整理的《C++编程风格(修订版)》——2.5 动态内存的一致性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Photoshop Lab修色圣典(修
- 下一篇: Effective C++ 条款47