C++ Primer : 第十三章 : 动态内存管理类
/* StrVec.h */ #ifndef _STRVEC_H_
#define _STRVEC_H_ #include <memory>
#include <string>
#include <vector>
#include <utility> class StrVec { public: StrVec() : first(nullptr), last_end(nullptr), cap(nullptr){}
StrVec(const StrVec&);
StrVec& operator = (const StrVec&);
~StrVec (); void push_back(std::string&); size_t size(){ return (last_end - first); }
size_t capacity(){ return (cap - first);} std::string* begin() const { return first; }
std::string* end() const { return last_end; } private: static std::allocator<std::string> alloc; // 分配元素 std::string* first; // first element pointer(begin())
std::string* last_end; // last_end element pointer(end())
std::string* cap; // capacity pointer std::pair<std::string*, std::string*> alloc_n_copy (const std::string*, const std::string*); void chk_n_alloc (){
if (size() == capacity())
reallocate();
} void free ();
void reallocate (); }; #endif // _STRVEC_H_
#include "StrVec.h"
StrVec::StrVec(const StrVec& s){
	auto newData =	alloc_n_copy(s.begin(), s.end());
	first		 =	newData.first;
	last_end	 =  cap = newData.second;
}
StrVec& StrVec::operator=(const StrVec& s){
	auto data = alloc_n_copy(s.begin(), s.end());
	free();
	first = data.first;
	last_end = cap = data.second;
	return *this;
}
StrVec::~StrVec(){
	free();
}
void StrVec::push_back(std::string& str){
	chk_n_alloc();
	alloc.construct(last_end++, str);
}
std::pair<std::string*, std::string*> StrVec::alloc_n_copy(const std::string* begin, const std::string* end){
	auto data = alloc.allocate(end - begin);
	return {data, uninitialized_copy(begin, end, data)};
}
void StrVec::free(){
	if (nullptr != first){
		for (auto p = last_end; p >= first;)
			alloc.destroy(--p);
		alloc.deallocate(first, cap - first);
	}
}
void StrVec::reallocate(){
	size_t newSize =  size() * 2;
	auto newdata   = alloc.allocate(newSize);
	auto dest  = newdata;
	auto fst   = first;
	// move the old elements
	for (size_t i = 0; i != size(); ++i)
		alloc.construct(dest++, std::move(*fst++));
	free();
	first		=	newdata;
	last_end	=	dest;
	cap			=	first + newSize;
}
当使用allcator重新分配内存时,我们应该移动原来的数据而不是拷贝,如果有大量的数据,拷贝会非常浪费时间和空间资源,因此我们用到了标准库函数std::move,它定义在有文件 <utility>中。
C++ Primer : 第十三章 : 动态内存管理类的更多相关文章
- [C++ Primer] : 第12章: 动态内存
		
动态内存与只能指针 静态内存用来保存局部static对象, 类static数据成员以及定义在任何函数之外的变量. 栈内存用来保存定义在函数内的非static对象. 分配在静态或栈内存中的对象由编译器自 ...
 - 【C++ Primer 第13章】5. 动态内存管理类
		
StrVec类的设计 [题目描述]:我们将实现标准库vector类的一个简化版本,我们所做的一个简化是不使用模板,我们类只用于string,因此,它被命名为StrVec. #include<io ...
 - C++ Primer : 第十二章 : 动态内存之shared_ptr类实例:StrBlob类
		
StrBlob是一个管理string的类,借助标准库容器vector,以及动态内存管理类shared_ptr,我们将vector保存在动态内存里,这样就能在多个对象之间共享内存. 定义StrBlob类 ...
 - (原创)动态内存管理练习  C++ std::vector<int> 模拟实现
		
今天看了primer C++的 “动态内存管理类”章节,里面的例子是模拟实现std::vector<std::string>的功能. 照抄之后发现编译不通过,有个库函数调用错误,就参考着自 ...
 - C++ Primer : 第十三章 : 拷贝控制之对象移动
		
右值引用 所谓的右值引用就是必须将引用绑定到右值的引用,我们通过&&来绑定到右值而不是&, 右值引用只能绑定到即将销毁的对象.右值引用也是引用,因此右值引用也只不过是对象的别名 ...
 - C++动态内存管理与源码剖析
		
引言 在本篇文章中,我们主要剖析c++中的动态内存管理,包括malloc.new expression.operator new.array new和allocator内存分配方法以及对应的内存释放方 ...
 - C++动态内存管理之shared_ptr、unique_ptr
		
C++中的动态内存管理是通过new和delete两个操作符来完成的.new操作符,为对象分配内存并调用对象所属类的构造函数,返回一个指向该对象的指针.delete调用时,销毁对象,并释放对象所在的内存 ...
 - uCGUI动态内存管理
		
动态内存的堆区 /* 堆区共用体定义 */ typedef union { /* 可以以4字节来访问堆区,也可以以1个字节来访问 */ ]; /* required for proper aligne ...
 - Keil C动态内存管理机制分析及改进(转)
		
源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...
 
随机推荐
- Trasformation中的公式报错误,错误数据行定位
			
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
 - oracle在windows下启动时报错ora-28056
			
windows下的的oracle ,实例启动时是会向windows操作系统的事件查看器--应用程序 部分写入启动信息的,并且这个写入行为无法用oracle 的参数或者其他手段去禁止. 若是事件查看器- ...
 - Ubuntu快捷键
			
https://linux.cn/article-3025-1.html 超级键操作 1.超级键(Win键)–打开dash. 2.长按超级键– 启动Launcher.并快捷键列表. 3.按住超级键,再 ...
 - linux chomd 学习
			
chomd -R 777 directory_name :递归地给directory目录下所有文件和子目录的属主分配读的权限 ------2016-10-31 -- source: Linux chm ...
 - Android:padding和android:layout_margin的区别
			
padding是站在父view的角度描述问题,它规定它里面的内容必须与这个父view边界的距离. margin则是站在自己的角度描述问题,规定自己和其他(上下左右)的view之间的距离
 - Linux 系统使用之 VMware Tools安装
			
Red Hat Enterprise Linux 4系统中安装VMware Tools 1. 必须以ROOT身份进入Linux 2. 进入linux系统,然后按下 CTRL+ALT组合键,进入主操作系 ...
 - Echarts的基本用法
			
首先需要到导入echatrs.js文件 <script src="dist/echarts.js"></script> 路径配置 require.confi ...
 - mysql查询结果输出到文件
			
mysql查询结果导出/输出/写入到文件 方法一: 直接执行命令: mysql> select count(1) from table into outfile '/tmp/test.xls' ...
 - PHP 二维码解码 (读取二维码)
			
#zbar wget http://ncu.dl.sourceforge.net/project/zbar/zbar/0.10/zbar-0.10.tar.bz2 yum install gtk2 g ...
 - (转)【深入浅出jQuery】源码浅析2--奇技淫巧
			
[深入浅出jQuery]源码浅析2--奇技淫巧 http://www.cnblogs.com/coco1s/p/5303041.html