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;
}