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