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