c++实现vector和shared pointer,需要具备基本的default constructor, constructor, copy constructor, move constructor, assignment operator, move assignment operator, destructor。并进行测试。
myVector.h:
#pragma once
#ifndef VECTOR_H
#define VECTOR_H
#include<iostream>
#include <cassert>
using namespace std;
template<typename T> class myVector {
private:
const size_t SPACE_SIZE = 64;//myVector each time increase space size
T* _array;
size_t _size;
size_t _capacity;
public:
//default constructor
myVector() :_array(nullptr), _size(0), _capacity(0)
{
cout << "In myVector default constructor..." << endl;
}
//constructor
myVector(size_t n, T value = 0)
{
cout << "In myVector constructor..." << endl;
_capacity = SPACE_SIZE;
while (n > _capacity)
{
_capacity += SPACE_SIZE;
}
_array = new T[_capacity];
_size = n;
while (n--)
{
_array[n] = value;
}
}
//copy constructor
myVector(const myVector<T>& other)
{
cout << "In myVector copy constructor..." << endl;
//*this = other;
this->_size = other._size;
this->_capacity = other._capacity;
this->_array = new T[_capacity];
memcpy(_array, other._array, sizeof(T) * _capacity);
}
//move constructor非 const 右值引用只能操作右值,程序执行结果中产生的临时对象(例如函数返回值、lambda 表达式等)既无名称也无法获取其存储地址,所以属于右值。
//当类中同时包含拷贝构造函数和移动构造函数时,如果使用临时对象初始化当前类的对象,编译器会优先调用移动构造函数来完成此操作。
myVector(myVector<int>&& other) :_array(nullptr), _size(0), _capacity(0)
{
cout << "In myVector move constructor ..." << endl;
_size = other._size;
_array = other._array;
_capacity = other._capacity;
other._size = 0;
other._array = nullptr;
other._capacity = 0;
}
//destructor
~myVector() {
if (this->_array)
{
delete[] this->_array;
}
}
//assignment operator
myVector<T>& operator=(const myVector& other)
{
cout << "In myVector assignment operator..." << endl;
if (this == &other)
{
return *this;
}
if (this->_array)
{
delete[] _array;
}
this->_array = new T[other._capacity];
this->_capacity = other._capacity;
this->_size = other._size;
memcpy(this->_array, other._array, _capacity * sizeof(T));
return *this;
}
myVector& operator=(myVector&& other)
{
cout << "In myVector move assignment operator..." << endl;
if (this != &other)
{
if (!_array)
delete[] _array;
_array = other._array;
_size = other._size;
_capacity = other._capacity;
other._size = 0;
other._capacity = 0;
other._array = nullptr;
}
return *this;
}
//T operator[](size_t index) {
// assert(index < this->_size);
// return _array[index];
//}
size_t size() {
return this->_size;
}
size_t capacity() {
return this->_capacity;
}
bool isEmpty() {
return this->_size == 0;
}
void push_back(const T& t) {
if (this->_size == this->_capacity) {
T* tmp = this->_array;
this->_array = new T[_capacity + SPACE_SIZE];
memcpy(this->_array, tmp, this->_size * sizeof(T));
this->_capacity += SPACE_SIZE;
delete[] tmp;
}
this->_size += 1;
_array[_size - 1] = t;
}
void insert(size_t pos, const T& t) {
assert(pos <= _size);
if (_size == _capacity) {
_capacity += SPACE_SIZE;
T* tmp = _array;
_array = new T[_capacity];
memcpy(_array, tmp, sizeof(T) * _size);
delete[] tmp;
}
for (size_t i = _size - 1; i >= pos; i--) {
_array[i + 1] = _array[i];
}
_array[pos] = t;
_size += 1;
}
void erase(size_t pos) {
assert(pos < _size);
for (size_t i = pos + 1; i < _size; i++) {
_array[i - 1] = _array[i];
}
_size--;
}
};
#endif
mySharePointer.h
//部分参考:https://blog.csdn.net/st125475466/article/details/48295775?utm_source=blogxgwz5
#pragma once
#ifndef MYSHAREPOINTER_H
#define MYSHAREPOINTER_H
#include "DebugDelete.h"
#include <functional>
#include <iostream>
//1.模板成员函数知道使用时编译器才去编译
template<typename T>class mySharePointer
{
public:
//默认构造函数
mySharePointer()
{
cout << "In mySharePointer default constructor..." << endl;
}
//显式定义构造函数,传递指针管理类型和删除器对象两个形参
explicit mySharePointer(T* t, std::function<void(T*)> d = DebugDelete()) :t(t), count(new size_t(1)), Deleter(d)
{
cout << "In mySharePointer constructor..." << endl;
}
//拷贝构造函数
mySharePointer(mySharePointer& sp) :count(sp.count), t(sp.t), Deleter(sp.Deleter)
{
cout << "In mySharePointer copy constructor..." << endl;
++* count;
}
//移动构造函数,mySharePointer<int> m(mySharePointer<int>(new int(30)))调用移动构造函数,若无,则调用拷贝构造函数
mySharePointer(mySharePointer&& sp) :count(sp.count), t(std::move(sp.t)), Deleter(std::move(sp.Deleter))
{
cout << "In mySharePointer move constructor..." << endl;
sp.t = nullptr;
}
//赋值函数
mySharePointer& operator=(mySharePointer& sp);
mySharePointer& operator=(mySharePointer&& other)
{
cout << "In mySharePointer move assignment operator..." << endl;
if (this != &other)
{
if (!t)
delete[] t;
t = other.t;
count = other.count;
other.count = nullptr;
other.t = nullptr;
}
return *this;
}
//返回指针指向的值
T& operator*() const { return *t; }
//重载->
T* operator->() const { return &this->operator*(); }
//reset
void reset() {
deconstructor();
}
void reset(T* p) {
if (t)
{
deconstructor();
t = p;
count = new size_t(1);
}
}
void reset(T* p, std::function<void(T*)> d) {
reset(p);
Deleter = d;
}
private:
std::size_t* count;//6.计数为不同对象的公共变量,固定义一个指针,指向共有内存
T* t;
std::function<void(T*)> Deleter;
void deconstructor();
};
template<typename T>
inline void mySharePointer<T>::deconstructor()
{
if (t)
{
--* count;
if (*count == 0)
{
Deleter(t);
delete count;
}
}
t = nullptr;
count = nullptr;
}
template<typename T>
inline mySharePointer<T>& mySharePointer<T>::operator=(mySharePointer& sp)
{
cout << "In mySharePointer assignment operator..." << endl;
++(*sp.count);
deconstructor();
count = sp.count;
t = sp.t;
Deleter = sp.Deleter;
return *this;
}
#endif
DebugDelete.h
#pragma once
#ifndef DEBUGDELETE_H
#define DEBUGDELETE_H
#include <iostream>
class DebugDelete
{
public:
DebugDelete(std::ostream& s = std::cerr) :os(s) {} //流无法被拷贝
template<typename T> void operator()(T* t)const
{
//os << "deleting ptr" << std::endl;
//std::cout << "t:" << t <<" &t:"<< &t <<" *t:" <<*t << std::endl;
delete t;
//std::cout << "t:" << t <<" &t:"<< &t <<" *t:" <<*t << std::endl;
}
private:
std::ostream& os;//流无法被拷贝
};
#endif
main.cpp
/**
Time:2021.3.7
*This program can be directly compiled to run in VS2019*/
#include<iostream>
#include"myVector.h"
#include "DebugDelete.h"
#include "mySharePointer.h"
#include <functional>
#include <utility>
#include <string>
using namespace std;
void mySharePointerTest()
{
cout << "******************mySharePointerTest*****************" << endl;
cout << "---------1----------" << endl;
mySharePointer<int> p(new int(20));
mySharePointer<int> s(new int(30));
cout << "---------2----------" << endl;
mySharePointer<int> q(s);
cout << "---------3----------" << endl;
s = p;
cout << "---------4----------" << endl;
mySharePointer<int> m(mySharePointer<int>(new int(30)));
int mm = *m;
cout << "---------5----------" << endl;
mySharePointer<std::string> n(mySharePointer<std::string>(new std::string("hello")));
n.reset();
m.reset(new int(32));
p.reset(new int(43), DebugDelete());
cout << "---------6----------" << endl;
mySharePointer<int> f = move(s);
cout << "---------7----------" << endl;
m = mySharePointer<int>(nullptr);
m = mySharePointer<int>(0);
m = move(m);
}
void myVectorTest()
{
cout << "******************myVectorTest********************" << endl;
cout << "---------1----------" << endl;
myVector<int> a(2);
cout << "---------2----------" << endl;
myVector<int> b;
a.push_back(0);
cout << "---------3----------" << endl;
b = a;
cout << "---------4----------" << endl;
myVector<int> c(a);
cout << "---------5----------" << endl;
myVector<int> f = move(a);//move() 函数,它可以将左值强制转换成对应的右值,由此便可以使用移动构造函数
cout << "---------6----------" << endl;
b = myVector <int>(1);
}
int main()
{
myVectorTest();
mySharePointerTest();
}