STL學習

xiboliha發表於2024-10-27

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

image-20241027165906550

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

相關文章