C++内存分配与对象构造的分离
作者:网络转载 发布时间:[ 2015/4/13 14:10:38 ] 推荐标签:C++ 内存 对象 构造
在C++中,我们基本用new(delete)操作符分配(释放)内存。new操作符为特定类型分配内存,并在新分配的内存中构造该类型的一个对象。new表达式自动运行合适的构造函数来初始化每个动态分配的类类型对象。即new表达式既分配了内存同时也构造了对象。
然而,我们一定会遇到这样的情况:预先分配用于创建新对象的内存,需要时在预先分配的内存中构造每个对象。即将内存分配与对象构造分开进行,这样做的理由是:
(1)在内存分配时构造对象很浪费,可能会创建从不使用的对象。
(2)当实际使用预先分配的对象时,被使用的对象很可能要重赋新值。
string* pstr = new string[5];
上面举了个不合适的例子(当然你应该用vector<string>来代替),毫无疑问被分配的5个string空间是被string默认构造函数初始化了,而且接下来你肯定得对pstr[0...4]重新赋值。所以new操作符这种分配特点会增加运行时开销。尤其是某些用户的类类型要求对象分配更快一些,做法通常是:预先分配用于创建新对象的内存,需要时在预先分配的内存中构造每个新对象。
一、分配原始内存
C++提供两种方法分配和释放未构造的原始内存:
(1)allocator类,它提供可感知类型的内存分配。这个类支持抽象接口,以分配内存并随后使用该内存保存对象。
(2)标准库中的operator new和operator delete,它们分配和释放需要大小的原始的,未类型化的内存。
1、allocator类
allocator类是一个模板,它提供类型化的内存分配以及对象构造与撤销。它支持的操作如下:
allocator类将内存分配和对象构造分开。当allocator对象分配内存的时,它分配适当大小并排列成保存给定类型对象的空间。它分配的内存是未被构造的,allocator的用户必须分别construct和destroy放置在该内存中的对象。
vector的自增长告诉我们:vector为了实现快速内存分配,其实际分配的空间要比当前需要的空间多一些。(实际空间因库的实现不同而不同),下面为了说明allocator的使用,我们简陋地实现STL vector中的push_back操作。
template <class T> class VECTOR
{
public:
VECTOR() : elements(NULL), first_free(NULL), end(NULL){}
void push_back(const T&);
private:
static allocator<T> alloc;
void reallocate();
T *elements;
T *first_free;
T *end;
};
elements:指向数组的第一个元素;first_free:指向后一个实际元素之后的那个元素;end:指向数组本身之后的那个元素。看下面这张图可能更清楚一点。
template <class T> void VECTOR<T>::push_back(const T& t)
{
if (first_free == end) //确认是否有可用空间
{
reallocate(); //分配新空间并复制现存元素
}
alloc.construct(first_free, t); //构造新元素
++first_free;
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11