本节书摘来自异步社区出版社《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 动态内存的一致性相关推荐

  1. 《C++编程风格(修订版)》——1.1 抽象

    本节书摘来自异步社区出版社<C++编程风格(修订版)>一书中的第1章,第1.1节,作者:[美]Tom Cargill,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  2. 《C++编程风格(修订版)》——3.2 继承作用域准则

    本节书摘来自异步社区出版社<C++编程风格(修订版)>一书中的第3章,第3.2节,作者:[美]Tom Cargill,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  3. C和指针之动态内存分配之编程练习3

    1.问题 编写一个函数,从标准输入读取一个字符串,把字符串复制到动态内存分配的内存中,并返回该字符串的拷贝,这个函数不应该对读入字符串的长度作任何限制!             2.代码实现 #inc ...

  4. Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组...

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:什么是静态内存什么又是动态内存呢? 静态内存:是指在程序开始运行时由编译 ...

  5. 第二章 面向对象的编程风格

    第二章 面向对象的编程风格 2.1 如何撰写函数 函数定义四要素:函数的返回类型.函数的名称.函数的参数列表.函数体 占位符(placeholder) 函数原型(function prototype) ...

  6. python 指针_C++的动态内存:C++的指针

    在C++里,指针(pointer)变量被用来存储内存地址.C++要求使用特定的类型来定义指针.这个类型被用来指示需要如何去解释内存地址里的数据.我们已经知道,在计算机的内部,内存存储的是1和0,而C+ ...

  7. Google C++编程风格整理(二)

    5.其他 C++ 特性 5.1. 引用参数 Tip 所以按引用传递的参数必须加上 const. 定义: 在 C 语言中, 如果函数需要修改变量的值, 参数必须为指针, 如 int foo(int *p ...

  8. Gogole C++ 编程风格(一)

    目的: 便于他人阅读代码,记录Gogole C++ 编程风格笔记 一.头文件 1.1.Self-contained 头文件 Tip: 所有的头文件都应该使用#define来防止头文件被多重包含,命名格 ...

  9. Python编程风格和设计模式

    http://blog.csdn.net/pipisorry/article/details/26840461 the Zen of Python Python的禅学 >>> imp ...

最新文章

  1. JS 总结之事件循环
  2. 重磅:ATT的《5G移动边缘计算白皮书》!
  3. ubuntu 12.04 配置vsftpd 服务,添加虚拟用户,ssl加密
  4. MAX2323E - 原理图系列
  5. jQuery-DOM操作之属性、class
  6. [禅悟人生]心平气和, 慢慢修行
  7. 作者:黎建辉(1973-),男,博士,中国科学院计算机网络信息中心研究员、博士生导师...
  8. 剑指offer——面试题7:用两个栈实现队列
  9. 光纤MPO端面脏了也会造成您所不知道的故障
  10. matlab圆形数据集,Matlab处理SPEI全球数据集
  11. 要不要升级到iOS16?iOS16有什么缺点?
  12. 阿里巴巴达摩院发布2019十大科技趋势:语音AI在特定领域通过图灵测试
  13. 多电量变送器在消防巡检设备中的应用
  14. 2019小程序发展趋势
  15. ubuntu服务器搭建静态网站
  16. redis的持久化方式RDB和AOF的区别
  17. 【经验篇】聊聊双非计算机硕士如何进大厂搞算法
  18. 魅族Android10内测招募答案,魅族flyme9内测招募答案
  19. matlab中im2bw
  20. linux课程思政方案,课程建设

热门文章

  1. GDCM:png文件转为dcm文件的测试程序
  2. Boost:自定义小矢量的测试程序
  3. ITK:读写矢量图像
  4. ITK:获取图像大小
  5. VTK:小部件之CompassWidget
  6. OpenCV蒙版图像make mask image的实例(附完整代码)
  7. C++使用数组的链表实现(附完整源码)
  8. C语言实现二叉树(附完整源码)
  9. C++STL的stack容器
  10. C++ Bitsets