1、vector.h
#pragma once
template <class T>
#include<string>//这里使用不带有.h的头文件
class vector{
public:
void PushBack(const T& x){
size_t size = Size();
check_capacity();
*_finish = x;
_finish++;
}
void PopBack(){
if (_start != _finish){
--_finish;
}
}
void Insert(size_t pos, const T& x){
size_t size = Size();
assert(pos <= size&&pos >= 0);
check_capacity();
for (size_t i = size; i > pos; i--){
_start[i] = _start[i - 1];
}
_start[pos] = x;
++_finish;
}
void Erase(size_t pos){
size_t size = Size();
assert(pos <= size&&pos >= 0);
for (size_t i = pos + 1; i < size; i++){
_start[i - 1] = _start[i];
}
--_finish;
}
vector()//构造函数
:_start(NULL)
, _finish(NULL)
, _endofstorage(NULL)
{}
vector(const vector<T>& v){
//拷贝的时候会涉及到开空间,
//如果拷贝的数据类型依然存在浅拷贝的问题则使用循环拷贝,切记不要使用memcpy
size_t size = v.Size();
T* tmp = new T[size];
for (size_t i = 0; i < size; i++){
tmp[i] = v[i];
}
delete[] _start;
_start = tmp;
_finish = _start + size;
_endofstorage = _finish;
//此处注意v的size一定要提前保存,不能使用_finish=_start+Size()
//因为原空间已经释放Size()=finish-start就会出错
}
~vector(){
if (_start){
delete[]_start;
_start = _finish = _endofstorage = NULL;
}
}
void Print(){
size_t size = Size();
for (size_t i = 0; i < size; i++){
cout << _start[i] << " ";
}
cout << endl;
}
size_t Size(){
return _finish - _start;
}
size_t Capacity(){
return _endofstorage - _start;
}
void check_capacity(){
//有错误
/*size_t size = Size();
size_t capacity = Capacity();
if (size >= capacity){
size_t n = 2 * capacity + 3;
T* tmp = new T[n];
delete[]_start;
memcpy(_start, tmp, sizeof(T)*size);
_start = tmp;
_finish = _start + size;
_endofstorage = _start + n;
}*/
if (size >= capacity){
size_t n = 2 * capacity + 3;
T* tmp = new T[n];
for (size_t i = 0; i < size; i++){
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = _start + size;
_endofstorage = _start + n;
}
}
bool Empty(){
return _start == _finish;
}
T& Front(){
return _start[0];
}
const T& Front()const{
return _start[0];
}
const T& Top()const{
return *(_finish - 1);
}
protected:
T* _start;
T* _finish;
T* _endofstorage;
};
说一下vector在检查空间不够用是开空间的情况下,会涉及深浅拷贝问题,使用memcpy函数来拷贝原来的空间和数据会出错
因为这个出错不是说所有的数据类型都会出错,而是想string这样的类型本来就涉及深浅拷贝,开空间还要在涉及一次深浅拷贝,所以就有二次深浅拷贝
为什么会出现这样的错误呢?
当字符长度不超过buf时,字符串存放在buf中,(buf是对象的成员)所以memcpy可以实现拷贝;但是当字符串超过那个长度就会用一个指针_start
来存放指向字符串的指针,拷贝空间时会析构原空间,所以析构掉_start
就会找不到对应的字符串了。
2、List.h
#pragma once
#include<assert.h>
template<class T>
class ListNode{
public:
ListNode<T>* _prev;
ListNode<T>* _next;
T _data;
ListNode(const T& x)
:_data(x)
, _next(NULL)
, _prev(NULL)
{}
};
template<class T>
class List{
typedef ListNode<T> Node;//ListNode是类名;ListNode<T>是类型
public:
List(){
_head = new Node(T());//利用缺省参数类型可以解决char、string等类型的参数传参
_head->_prev = _head;
_head->_next = _head;
}
~List(){
delete _head;
_head = NULL;
}
void Insert(Node* pos, const T& x){
assert(pos);
//不论什么位置、有无节点都可以涵盖
Node* pre = pos->_prev;
Node* new_node = new Node(x);
pre->_next = new_node;
new_node->_prev = pre;
new_node->_next = pos;
pos->_prev = new_node;
}
void Erase(Node* pos){
assert(pos || _head->_next != _head);
Node* pre = pos->_prev;
Node* next = pos->_next;
delete pos;
pre->_next = next;
next->_prev = pre;
}
Node* Find(const T& x){
/*if (head->_next == head){
return NULL;
}*/
Node* cur = _head->_next;
while (cur != _head){
if (cur->_data == x){
return cur;
}
cur = cur->_next;
}
return NULL;
}
void PushBack(const T& x){
Insert(_head, x);
}
void PopBack(){
Erase(_head->_prev);
}
void PushFront(const T& x){
Insert(_head->_next, x);
}
void PopFront(){
Erase(_head->_next);
}
//拷贝构造
List(const List<T>& l){
_head = new Node(T());
_head->_prev = _head;
_head->_next = _head;
Node* cur = (l._head)->_next;
while (cur != l._head){
this->PushBack(cur->_data);
cur = cur->_next;
}
}
List<T>& operator=(const List<T>& l){
if (this != &l){
Node* cur = (l._head)->_next;
while (cur != _head){
this->PushBack(cur->_data);
cur = cur->_next;
}
}
return *this;
}
size_t Size(){
Node* cur = _head->_next;
size_t size = 0;
while (cur != _head){
size++;
cur = cur->_next;
}
return size;
}
void Clear(){
//删除头结点以外的节点
Node* cur = _head->_next;
while (cur != _head){
Node* next = cur->_next;
delete cur;
cur = next;
}
_head->_prev = _head;
_head->_next = _head;
}
bool Empty(){
return _head->_next == _head;
}
const T& Front()const{
return _head->_next->_data;
}
void Print(){
Node* cur = _head->_next;
while (cur != _head){
cout << cur->_data << " ";
cur = cur->_next;
}
}
protected:
Node* _head;
};
3、Queue.h
#include"List.h"
#pragma once
template <class T, class Container>
class Queue{
public:
void Push(const T& x){
_con.PushBack(x);
}
void Pop(){
_con.PopFront();
}
const T& Front()const{
return _con.Front();
}
size_t Size(){
return _con.Size();
}
bool Empty(){
return _con.Empty();
}
protected:
Container _con;
};
4、Stack.h
#include"vector.h"
#pragma once
template <class T,class Container>
class Stack{
public:
void Push(const T& x){
_con.PushBack(x);
}
void Pop(){
_con.PopBack();
}
const T& Top()const{
return _con.Top();
}
size_t Size(){
return _con.Size();
}
bool Empty(){
return _con.Empty();
}
protected:
Container _con;
//Container <T> _con;在容器这里将类型统一,
//避免Stack<int,vector<char>> s;大于127时造成的缺陷
};