vector实现(带迭代器和allotor,非模板)

vector的实现,说说大体框架吧。

1.vector中通过静态私有allotor的对象来动态实时分配空间。

每次插入新内容是,都会检测空间是否足够,不够的话,重现分配现在大小的两倍,将内容拷贝过去。杀掉旧的空间。修改vector指针成员。这里有一点注意到是,类的静态成员要在类外进行定义,不然会报无法解析的外部符号错误。因此,在.cpp文件开头中有allocator<string>like_vector::alloc;

2.iterator用嵌套类实现。

嵌套类内,可以访问外层类的私有成员,而外层类不能访问嵌套类的私有成员。

这里为什么用嵌套类呢,主要是标准中的iterator定义的时候是vector<string>::iterator a;

所以呢,我也这样模仿,让iterator作为vector内部的类。

3.然后剩余的就是vector中基本功能的实现了。

程序如下:

.h文件:

#ifndef PCH_H
#define PCH_H
#include<memory>
#include<string>
//这个头文件实际是没有必要的,这里只是为了测试free函数用的
#include<iostream>
using namespace std;
// vector简单版实现
class like_vector {
public:
	//迭代器(内部嵌套类)
	class iterator;
	like_vector():
		first_element(nullptr),first_free(nullptr),tail(nullptr){}
	//拷贝构造函数
	like_vector(const like_vector&);
	//拷贝复制函数
	like_vector& operator =(const like_vector&);
	//析构函数
	~like_vector();

	//返回实际使用空间大小,以string为单位
	int size()const;
	//返回所有分配空间的大小,以string为单位
	int capacity()const;
	iterator begin() const;
	iterator end() const;
	//在尾部插入一个string元素
	void push_back(const string&);
	
private:
	//通过alloc对象来分配内存空间(所有vector<string>的对象都公用这一个alloc对象)
   static allocator<string> alloc;
	//指向内存首地址的指针
	string* first_element;
	//指向第一个未用内存地址的指针
	string* first_free;
	//指向内存空间最后一个内存空间后面的地址的指针
	string* tail;
	//检查空间是否够用
	void check_n_alloc();
	//重新分配空间并且将就内容复制
	void rellocate();
	//回收空间
	void free();

};
class like_vector::iterator {
public:
	iterator(string* a=nullptr):
		ptr(a){}
	//拷贝复制函数
	iterator& operator =(const iterator& a)
	{ ptr = a.ptr; return *this; }
	//*运算符
	string& operator *() {
		return *ptr;
	}
	//->运算符
	string* operator ->() {
		return ptr;
	}
	//这里++运算符仅适用于前置++哦
	iterator& operator ++() {
		++ptr;
		return *this;
	}
	bool operator !=(const iterator& a) {
		return (ptr != a.ptr);
	}
	iterator operator +(int a) {
		ptr += a;
		return *this;
	}
	iterator operator -(int a) {
		ptr -= a;
		return *this;
	}
private:
	string* ptr;
};
#endif
/*最重要的是分配空间,这里呢是通过对malloc和free函数封装的类allocteor完成的,做为成员变量
还需要一个嵌套迭代器类,然后们能够返回相应的地带其,
最后就是提供的操作了*/
/*总结:
对于出现无法解析的外部符号的问题,一般的三种错误
1.未添加头文件
2.未添加相应的库文件。好吧,这个暂时我还不太清楚
3.这个应该是这次犯的错误,类中定义的静态成员变量没有在类外进行初始化
*/

.cpp文件:

#include "pch.h"
//这里要把静态成员变量给重新定义一下,不然会报无法解析的外部符号错误
allocator<string>like_vector::alloc;
//拷贝构造函数
like_vector::like_vector(const like_vector& a) {
	//1.分配足够大的空间
	first_element=alloc.allocate(a.capacity());
	//2.将内容拷贝过来
	auto copy_first_element = first_element;       
	auto a_copy_first_element = a.first_element; //参数为const,我们只能用变量结束a.first_element,然后遍历++
	for (size_t i = 0; i != a.size(); ++i)
		alloc.construct(copy_first_element++, *a_copy_first_element++);
	//3.修改成员
	first_free = first_element + a.size();
	tail = first_element + a.capacity();
}
//拷贝复制函数
like_vector& like_vector::operator =(const like_vector& a) {
	//1.分配足够大的空间
	auto recieve_first_element = alloc.allocate(a.capacity());
	//2.将内容进行拷贝
	auto copy_recieve_first_element = recieve_first_element;
	auto a_copy_first_element = a.first_element;
	for (size_t i = 0; i != a.size(); ++i)
		alloc.construct(copy_recieve_first_element++, *a_copy_first_element++);
	//3.杀掉原本的空间
	free();
	//4.修改成员
	first_element = recieve_first_element;
	first_free = first_element + a.size();
	tail = first_element + a.capacity();
	return *this;
}
//析构函数
like_vector::~like_vector() {
	free();
}
int like_vector::size()const {
	//这里就算是指针为nullptr也是可以进行-操作的,但是呢,不能*和->操作
	return first_free - first_element;
}
int like_vector::capacity()const {
	return tail - first_element;
}
//这里我们返回临时对象就可以
like_vector::iterator like_vector::begin()const {
	return iterator(first_element);
}
like_vector::iterator like_vector::end()const {
	return iterator(first_free);
}
void like_vector::push_back(const string& a) {
	//1.查看空间是否足够
	check_n_alloc();
	//2.插入新内容
	alloc.construct(first_free++, a);

}
//检查空间是否足够
void like_vector::check_n_alloc() {
	if (first_free == tail)
		rellocate();
}
//当空间不够时重新分配空间
void like_vector::rellocate() {
	//1.分配更多的空间
	//如果size()为0则分配1个空间,如果不为0,则分配二倍空间
	auto newcapacity = size() ? 2 * size() : 1;
	auto newdata = alloc.allocate(newcapacity);  //这里返回的newdata是一个void类型的指针
	//2.将就内容复制过去
	auto size_length = size();  //将原来的有数据长度保存
	auto dest = newdata;
	auto elem = first_element;
	if (elem != nullptr) {
		for (size_t i = 0; i != size(); ++i)
			//consturct函数第一个参数接受一个指向动态分配内存的string类型的指针,第二个参数做初始化的量,将这个量传递给构造函数进行
			//初始化
			alloc.construct(dest++, *elem++);
		//3.删除掉旧的空间
		free();//我们自己定义的函数哦,不是标准库中的那个free函数
	}
	//4.更新类中的成员变量
	first_element = newdata;
	first_free = first_element + size_length;
	tail = first_element + newcapacity;
}
void like_vector::free() {
	//1.销毁掉内部数据
	if (first_element) {
		for (auto p = first_element; p != first_free; ++p) {
			cout << "杀掉" << endl;
			alloc.destroy(p);//这里destroy函数会调用string的析构函数,来释放器分配的动态内存
		}
	}
	//2.归还空间
	alloc.deallocate(first_element, tail - first_element);
}




main文件测试程序:

#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
	like_vector a;
	//测试push_back以及世界分配的内存大小
	cout << a.size() << endl;
	cout << a.capacity() << endl;
	a.push_back("xiaoming");
	cout << a.size() << endl;
	cout << a.capacity() << endl;
	cout << *a.begin() << endl;
	a.push_back("luo");
	cout << a.size() << endl;
	cout << a.capacity() << endl;
	cout << *(++a.begin()) << endl;
	a.push_back("hello");
	cout << a.size() << endl;
	cout << a.capacity() << endl;
	cout << *(a.begin()+2) << endl;
	a.push_back("tomorrow");
	cout << a.size() << endl;
	cout << a.capacity() << endl;
	cout << *(a.begin()+3) << endl;
	a.push_back("happy");
	cout << a.size() << endl;
	cout << a.capacity() << endl;
	cout << *(a.begin()+4) << endl;
	/*到这一步之前,我们可以看到我们push_back的内容确实写到了实际的存储空间中,并且嵌套类迭代器也是可用的*/
	//这里难道是end()函数除了错误吗?
	for (auto b = a.begin(); b != a.end(); ++b) {
		cout << *b << endl;
	}
	//测试拷贝构造函数
	like_vector b(a);
	cout << b.size() << endl;
	cout << b.capacity() << endl;
	for (auto a = b.begin(); a!= b.end(); ++a)
		cout << *a << endl;
	//测试拷贝复制函数
	like_vector c;
	c = b;
	cout << c.size() << endl;
	cout << c.capacity() << endl;
	for (auto a = c.begin(); a != c.end(); ++a) {
		cout << *a << endl;
	}
}

执行结果如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值