手写STL源码
模板
//TemplateDemo
#include<iostream>
using namespace std;
//交换两个变量
void MySwap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
//使用模板--自适应类型生成函数,地址不同
//函数重载和模板函数冲突,优先调用普通函数,或者使用<T>()显示调用
//不支持隐式转换
template<typename T>
void MyTSwap(T& a, T& b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
MyTSwap(a, b);
MyPrint(a, b);
}
操作符重载
class Complex
{
public:
double real;
double image;
Complex(double real, double image) :real(real), image(image) {}
Complex Add(Complex& other)
{
return Complex(this->real + other.real, this->image + other.real);
}
Complex Mulitply(Complex& other)
{
double a = this->real;
double b = this->image;
double c = other.real;
double d = other.image;
return Complex(a * c - b * d, b * c + a * d);
}
Complex operator+(Complex& other)
{
return Complex(this->real + other.real, this->image + other.real);
}
Complex operator*(Complex& other)
{
double a = this->real;
double b = this->image;
double c = other.real;
double d = other.image;
return Complex(a * c - b * d, b * c + a * d);
}
};
ostream& operator<<(ostream cout,const Complex& other)
{
cout << other.real << "," << other.image << "i";
return cout;//链式
}
尝试一个简易vector
#include<iostream>
using namespace std;
template<typename T>
class MyVector
{
public:
typedef T value;
typedef T* iterator;
typedef t& reference;
public:
MyVector(int len = 0) :v_len(len), v_Data(nullptr), start(nullptr), pos(0)
{
if (len > 0)
{
//创建数组
v_Data = new value[len];
start = v_Data;
}
}
~MyVector()
{
delete[]v_Data;
}
void push_back(const value& v)
{
if (v_len != pos)
{
*(start + pos) = v;
pos++;
}
else
{
cout << "越界" << endl;
}
}
inline value pop_back()
{
--pos;
return *(start + pos);
}
int size()
{
return this->v_len;
}
iterator begin()
{
return this->start;
}
iterator end()
{
return this->start + pos;
}
value& operator[](int n)
{
if (n <= pos)
{
return *(start + n);
}
else
{
cout << "越界" << endl;
}
}
protected:
iterator v_Data;
iterator start;
int v_len;
int pos;
};
template<typename T>
ostream& operator<<(ostream& cout, MyVector<T> vec)
{
for (int i = 0; i < vec.size(); i++)
{
vec.push_back(i);
}
return cout;
}
int main()
{
MyVector<int> vec(10);
for (int i = 0; i < vec.size(); i++)
{
vec.push_back(i);
}
cout << vec << endl;
for (int i = 0; i < vec.size(); i++) {
vec[i] = 100;
}
cout << vec << endl;
//for (MyVector<int>::iterator it = vec.begin(); it != vec.end(); it++)
//{
// cout << *it << "," << endl;
//}
}
引用,move剖析
- 左值:有名字,在内存中有自己的地址
- 右值:除了字符串之外的字面值(true nullptr...) 返回类型为非引用的函数调用 算数表达式
- 左值引用的本质是一个不能变的指针(常量指针),定义时需要初始化
- 移动语义:std::move() 将左值转换成右值 转移资源--节省内存空间
#include<iostream>
#include <vector>
using namespace std;
class Student
{
public:
char* name;
int size;
Student(int size = 0) :size(size), name(nullptr)
{
if (size > 0)
{
name = new char[size];
for (int i = 0; i < size; i++)
{
name[i] = 'a';
}
}
}
//深拷贝,重新开辟空间
Student(const Student& stu)
{
size = stu.size;
name = new char[size];
for (int i = 0; i < size; i++)
{
name[i] = stu.name[i];
}
}
//浅拷贝 指向同一片内存
//出现指针悬挂问题--在析构的时候会重复删除同一片空间
Student(Student& stu)
{
size = stu.size;
name = stu.name;
}
Student(Student&& stu)
{
size = stu.size;
name = stu.name;
stu.name = nullptr;//移动构造,把别人的占为己有,省去重新开辟空间的过程
}
~Student()
{
delete name;
}
};
int main()
{
vector<Student> school;
Student stu(7);
school.push_back(std::move(stu));
}
//目的是返回右值引用
//T&&万能引用
typename<typename T>
typename remove_reference<T>::type&& move(T&& t)
{
return static_case<typename remove_reference<T>::type&&>(t);//类型转换,将t转换为右值引用
}
//类型萃取
template<typename T>
struct remove_reference<T&&>
{
typedef T type;
}
template<typename T&>
struct remove_reference<T&&>
{
typedef T type;
}
template<typename T&&>
struct remove_reference<T&&>
{
typedef T type;
}