C++:mstring类的继续实现——迭代器

10_28

1.程序目的

模拟实现:把现实中的事物当作数据放到程序中
前端——展现数据
网络——传输数据
服务器——处理数据
数据库——存储数据
数据操作——增删改查

2.迭代器

定义:指向容器内部数据的一个指针,本质是一个对象
存在意义:当进行增加或者和删除操作之后,一定要重新获取迭代器,因为增加或者删除的操作有可能会造成迭代器失效
迭代器不能返回end,返回end代表返回的是一个无效的操作
作业:使用迭代器进行增删改查
对于常对象的迭代器,是const_iterstor Cbegin()

只要进行插入操作,再插入之前获取的迭代器都有可能失效
引用:交叉引用

string::iterator it1=s1.begin();
it1++;
string::iteratro it=s1.begin();
for(;it!=s1.end();it++)
{
    
    
	if(*it=='3')
	{
    
    
		it=s1.insert(it,'p');
		cout<<*it<<"";
		it++;
	}
	cout<<it*<<"";
}
vector<int>v1;
for(int i=0;i<10;i++)
{
    
    
	v1.push.back(i);
}
vector<int>::iterator it1 =v1.begin();
for(;it1!=v1.end;it++)
{
    
    
	cout<<*it1<<"";
}
cout<<endl;

3.区分和重载

new operator(常用)-不可重载
new(申请内存,调用构造函数)-opreator new-可以重载
delete operator(常用)-不可重载
delete(需要调用析构函数, 内存释放)-operator delete-可以重载

对operator new和operator delete进行重载

void*operator new(size_t size)
{
    
    
	cout<<"void*operator new(size_t size)"<<denl;
	void*p=malloc(size);
	return p;
}
void operator delete(void*p)
{
    
    
	cout<<"void operator delete(void*p)"<<endl;
	free(p);
}

4.系统调用(《程序员自我修养》)

New和delete作用

堆上内存属于外部资源,释放、申请外部资源。用户没有权限,内核态有权限;堆上的内存申请和释放的过程需要内核态完成,从用户态切换到内核态——系统调用(cout,printf,cin,scanf等等不依赖外部库函数)

5.内存池

用户态自己维护的一大段内存,从堆上申请自己维护。
重载new和delete相当于留下了一个可修改的端口,可以指定内存的申请和内存池,C++自带内存池 ——Alloc

(1)mstring.h

#ifndef MSTRING_H
#define MSTRING_H
#include<iostream>
#include"mstring_iterator.h"
#include<mutex>
using namespace std;


#define MSTRING_MORE_SIZE sizeof(int)
#define DEFEALT_LEN (10+MSTRING_MORE_SIZE)

class Mstring
{
    
    
public:
	typedef Mstring_iterator iterator;
	Mstring(const char* str = NULL);
	Mstring(const Mstring& src);
	Mstring& operator=(const Mstring& src);
	~Mstring();

	void push_back(char c);
	void pop_back();
	char back()const;
	char front()const;
	bool empty()const;
	int size()const;

	Mstring operator+(const Mstring& str)const;
	char& operator[](int pos);
	char operator[](int pos)const;

	iterator begin()
	{
    
    
		return iterator(*this, 0);
	}

	iterator end()
	{
    
    
		return iterator(*this, _val_len);
	}
	iterator insert(iterator it, char val) 
	{
    
    
		//判断是否独有
		if (get_num() > 1)
		{
    
    
			write_copy();
		}

		//扩容
		if (full())
		{
    
    
			revert();
		}

		iterator it1 = end();
		iterator it2 = it1 - 1;

		for (; it1 != it; it1--, it2--)
		{
    
    
			*it1 = *it2;
		}
		*it = val;
		_val_len++;

		return it;
	}
	iterator erase(iterator it)
	{
    
    
		//判断是否独有
		if (get_num() > 1)
		{
    
    
			write_copy();
		}
		
		//判空
		if (empty())
		{
    
    
			return it;
		}

		iterator it1 = it;
		iterator it2 = it + 1;
		for (; it2 != end(); it1++, it2++)
		{
    
    
			*it1 = *it2;
		}

		_val_len--;
		return it;
	}

	friend ostream& operator<<(ostream& out, const Mstring& src);
	friend istream& operator>>(istream& in, Mstring& src);
private:
	bool full()const;
	void revert();
	void init_num();
	int& get_num();
	int get_num()const;
	const char* get_str_begin()const;
	char* get_str_begin();
	void write_copy();
	int down_num();//引用计数-1
	int up_num();//引用计数+1

	char* _str;//能否直接使用浅拷贝------怎么加引用计数
	int _len;//当前空间总长度
	int _val_len;//已经占用的长度,实际数据数量
	static mutex* _lock;
};

#endif

(2)mstring.h_iterator.h

#ifndef MSTRING_ITERATOR_H
#define MSTRING_ITERATOR_H
#include"mstring.h"
class Mstring;

class Mstring_iterator
{
    
    
public:
	Mstring_iterator(Mstring& mstr, int pos)//构造函数
		:_mstr(mstr),_pos(pos)//声明是放在哪一个引用中
	{
    
    
	}
	Mstring_iterator(const Mstring_iterator& src)//拷贝构造
		:_mstr(src._mstr), _pos(src._pos)
	{
    
    
	}
	Mstring_iterator& operator=(const Mstring_iterator& src)
	{
    
    
		if (&_mstr != &src._mstr)
		{
    
    
			return *this;
		}
		_pos = src._pos;
		return *this;
	}

	bool operator !=(const Mstring_iterator& src)
	{
    
    
		if (&_mstr != &src._mstr || _pos != src._pos)
		{
    
    
			return true;
		}
		return false;
	}

	bool operator ==(const Mstring_iterator& src)
	{
    
    
		if (&_mstr == &src._mstr && _pos == src._pos)//指向同一个容器,而且指向容器的同一个位置,才代表指向迭代器是相同的
		{
    
    
			return true;
		}
		return false;
	}

	Mstring_iterator& operator++()//前置++(迭代器不用考虑越界问题)
	{
    
    
		_pos++;
		return *this;
	}
	Mstring_iterator operator++(int)//后置++
	{
    
    
		int pos = _pos;
		_pos++;
		return Mstring_iterator(_mstr, pos);
	}

	Mstring_iterator& operator--()
	{
    
    
		_pos--;
		return *this;
	}
	Mstring_iterator operator--(int)
	{
    
    
		int pos = _pos;
		_pos--;
		return Mstring_iterator(_mstr, pos);
	}

	Mstring_iterator operator+(int val)//迭代器加法
	{
    
    
		return Mstring_iterator(_mstr, _pos+val);
	}

	Mstring_iterator operator-(int val)//迭代器减法
	{
    
    
		return Mstring_iterator(_mstr, _pos - val);
	}

	char& operator*();//解引用运算符重载
private:
	Mstring& _mstr;
	int _pos;
};


#endif

(3)msrting.cpp

#include"mstring.h"

mutex* Mstring::_lock = new mutex();

Mstring::Mstring(const char* str)
{
    
    
	if (NULL == str)
	{
    
    
		_len = DEFEALT_LEN;
		_val_len = 0;
		_str = new char[_len];
		memset(_str, 0, _len);
		init_num();
		return;
	}

	_val_len = strlen(str);

	//加上引用计数占的空间
	_len = _val_len + 1 + MSTRING_MORE_SIZE;
	_str = new char[_len];
	memset(_str, 0, _len);

	for (int i = 0; i < _val_len; i++)
	{
    
    
		get_str_begin()[i] = str[i];
	}
	init_num();
}

Mstring::Mstring(const Mstring& src)
{
    
    
	_val_len = src._val_len;
	_len = src._len;
	_str = src._str;
	//让引用计数+1
	up_num();
}

Mstring& Mstring::operator=(const Mstring& src)
{
    
    
	if (&src == this)
	{
    
    
		return *this;
	}
	_val_len = src._val_len;
	_len = src._len;
	_str = src._str;
	up_num();

	return *this;
}

Mstring::~Mstring()
{
    
    
	//将引用计数-1
	down_num();

	//查看当前是否还有人引用
	if (0 == get_num())
	{
    
    
		delete[]_str;
	}
}

void Mstring::push_back(char c)
{
    
    
	//判断是否一个人独有
	if (get_num() > 1)
	{
    
    
		//写时拷贝,给分配独有的空间
		write_copy();
	}

	if (full())
	{
    
    
		revert();
	}

	get_str_begin()[_val_len] = c;
	_val_len++;
}

void Mstring::pop_back()
{
    
    
	if (get_num() > 1)
	{
    
    
		write_copy();
	}

	if (empty())
	{
    
    
		return;
	}

	_val_len--;
}

char Mstring::back()const
{
    
    
	if (empty())
	{
    
    
		return 0;
	}

	return get_str_begin()[_val_len - 1];
}

char Mstring::front()const
{
    
    
	if (empty())
	{
    
    
		return 0;
	}

	return get_str_begin()[0];
}

bool Mstring::empty()const
{
    
    
	return _val_len == 0;
}

Mstring Mstring::operator+(const Mstring& str)const
{
    
    
	char* p;
	int len = _val_len + str._val_len + 1;
	p = new char[len];
	memset(p, 0, len);

	//进行数据拷贝-----将两个字符串的数据拼接起来
	int i = 0;
	for (; i < _val_len; i++)
	{
    
    
		p[i] = get_str_begin()[i];
	}

	for (int j = 0; j < str._val_len; j++, i++)
	{
    
    
		p[i] = str.get_str_begin()[j];
	}

	return p;
}

char& Mstring::operator[](int pos)
{
    
    
	if (get_num() > 1)
	{
    
    
		write_copy();
	}
	return  get_str_begin()[pos];
}

char Mstring::operator[](int pos)const
{
    
    
	return  get_str_begin()[pos];
}

bool Mstring::full()const
{
    
    
	return _val_len == _len - 1 - MSTRING_MORE_SIZE;
}

void Mstring::revert()
{
    
    
	if (get_num() > 1)
	{
    
    
		write_copy();
	}

	_len = _len << 1;

	char* p = new char[_len];
	memset(p, 0, _len);

	for(int i = 0;i<_val_len+MSTRING_MORE_SIZE;i++)
	{
    
    
		p[i] = _str[i];
	}

	if (down_num() == 0)
	{
    
    
		delete[]_str;
	}

	_str = p;
}

int Mstring::size()const
{
    
    
	return _val_len;
}

//初始化引用计数
void Mstring::init_num()
{
    
    
	get_num() = 1;
}

//获取引用计数
int& Mstring::get_num()
{
    
    
	return *((int*)_str);
}

//引用计数-1
int Mstring::down_num()
{
    
    
	_lock->lock();
	int num = --get_num();
	_lock->unlock();
	return num;
}

//引用计数+1
int Mstring::up_num()
{
    
    
	//get_lock()->lock();
	_lock->lock();
	/*
	while(1)
	{
		if(_lock->a == 0)
		{
			_lock->a = 1;
			break;
		}
		sleep(10);
	}
	
	*/
	int num = ++get_num();
	_lock->unlock();
	/*
	_lock->a = 0;
	*/

	return num;
}


//获取引用计数
int Mstring::get_num()const
{
    
    
	return *((int*)_str);
}

//获取字符串的开头指针
char* Mstring::get_str_begin()
{
    
    
	return _str + MSTRING_MORE_SIZE;
}

//获取字符串的开头指针
const char* Mstring::get_str_begin()const
{
    
    
	return _str + MSTRING_MORE_SIZE;
}

//写时拷贝
void Mstring::write_copy()
{
    
    
	char* p = new char[_len];

	//将所有的数据全部拷贝过来
	for (int i = 0; i < _len; i++)
	{
    
    
		p[i] = _str[i];
	}

	//改变原来指向的内存的引用计数
	if (0 == down_num())
	{
    
    
		delete[]_str;
	}

	//将当前引用计数改为1
	_str = p;
	init_num();
}

ostream& operator<<(ostream& out, const Mstring& src)
{
    
    
	for (int i = 0; i < src.size(); i++)
	{
    
    
		out << src.get_str_begin()[i];
	}
	out << "     :::::num:::" << src.get_num();
	out << endl;
	return out;
}

istream& operator>>(istream& in, Mstring& src)
{
    
    
	if (src.get_num() > 1)
	{
    
    
		src.write_copy();
	}

	char tmp[1024];
	in >> tmp;
	
	src = tmp;
	return in;
}


char& Mstring_iterator::operator*()
{
    
    
	return _mstr[_pos];
}


(4)main(mstring).cpp

#include<iostream>
#include"mstring.h"
#include<string>
#include<vector>
using namespace std;


/*
迭代器存在的意义


*/
int main()
{
    
    
	//对于常对象的迭代器,是const_iterator s1.cbegin(); s1.cend()
	Mstring s1 = "123456";
	Mstring::iterator it = s1.begin();
	for (; it != s1.end(); it++)
	{
    
    
		if (*it == '3')
		{
    
    
			it = s1.erase(it);
			//it = s1.insert(it, 'p');
			//cout << *it << " ";
			//it++;

		}
		//cout << *it << " ";
		//if (*it == '3')
		//{
    
    
			//*it = '9';
		//}
	}
	cout << endl;

	cout << s1 << endl;


#if 0
	string s1 = "123456";

	/*
	当进行增加或者删除的操作之后,一定要重新获取迭代器
	因为增加或者删除的操作有可能造成迭代器失效
	*/

	//迭代器-------指向容器内部数据的一个指针--本质是对象
	string::iterator it1 = s1.begin();
	it1++;

	//begin()  end()    [  )

	//使用迭代器进行增删改查
	string::iterator it = s1.begin();
	for (; it != s1.end(); it++)
	{
    
    
		//*it = 'i';
		if (*it == '3')
		{
    
    
			it = s1.erase(it);
			//it = s1.insert(it, 'p');
			//cout << *it << " ";
			//it++;
		}
		cout << *it << " ";
	}
	/*
	死循环
	it = s1.insert(it, 'p');
	it = s1.insert(it, 'p');
	it = s1.insert(it, 'p');
	it = s1.insert(it, 'p');
	it = s1.insert(it, 'p');
	it = s1.insert(it, 'p');
	it = s1.insert(it, 'p');
	*/
	cout << endl;
	cout << s1 << endl;
	it1 = s1.begin();
	cout << *it1 << endl;





	/*
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;


	
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	vector<int>::iterator it1 = v1.begin();
	for (; it1 != v1.end(); it1++)
	{
		cout << *it1 << " ";
	}
	cout << endl;
	*/

#endif
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_48580892/article/details/121021033
今日推荐