c++ - 为什么没有 realloc 等同于 new/delete 系列?
问题描述
正如标题所说,我知道/系列运算符realloc
中没有与 C 等效的。new
delete
我已经发现这个问题稍微触及了这个主题,但它并没有真正回答“为什么”。
我的问题是:
- 为什么能够重新分配对象是个坏主意?
- 为什么改变对象的大小是个坏主意?(实现一个集合似乎是一个对象改变其大小的完全正当理由。)
- 在这些情况下会违反什么规则,为什么这条规则客观上是好的?
解决方案
Realloc 有两种行为,其中一种在 C++ 对象模型中是不可接受的。Realloc 可以增加一块存储的大小,或者它可以分配新的存储并将旧存储中的所有内容复制到新存储中。
问题是,C++ 并不认为对象只是比特袋。它们是具有不变量的活生生的呼吸类型。而且其中一些不变量不能容忍它们的位被很好地复制。
在 C++ 中,复制对象的位并不意味着您有效地复制了该对象。这仅适用于可简单复制的类型,并且有很多类型不可简单复制。
因此,C++ realloc 等价物不能用于任何分配。您需要将调用拆分为两个单独的调用:一个尝试扩展内存,如果不能,则不执行任何操作,以及您将使用现有 C++ 技术手动复制到的常规堆分配调用。
作为一个例子,许多std::list
实现在对象本身中存储了一个终止节点,std::list
用于表示链表的开始/结束。如果您只是简单地复制其位,则指向终止节点的指针将指向现在已消失的旧分配。
那很糟。
为了允许对象具有访问这些类型的代码可以维护的任意类不变量,有必要将对象视为不仅仅是其对象表示的位。并且大多数 C++ 类型都保留了一些不变量,其对象表示无法在按位复制中存活。
推荐阅读
- java - 字节伙伴将实例方法委托给静态方法,将实例作为参数传递
- latex - 乳胶人偶;在绘制四部分图时,一个(b)比另一个浮动得更高,我找不到任何原因
- java - 当成员为最终成员时,向 Trie 插入一个新元素
- javascript - 如何修复我的 Tilemap?为什么能得到完整的地图?只有 JAVASCRIPT
- sql - SQL,成对行之间的操作
- flutter - 颤振错误(类型'列表
' 不是类型 'Map 的子类型 ') - reactjs - 无法从不同的组件访问功能
- javascript - 单击按钮时显示 HTML5 本机日期选择器
- serial-port - 以高波特率连续 UART 传输 RS-232
- c++ - 如何从 csv 文件读取 C++ 中的类到数组或公共类标记中?