// 簡易stack
#include<cstdio>
#include<iostream>
using namespace std;
template<typename T>
class stack {
private:
T* pstack; int capacity, top,size=0;
public:
stack(int c = 5):top(-1), capacity(c) {
pstack = new T[capacity];
cout << "stack init" << endl;
}
// 拷貝構造函數
stack(const stack<T> & s):capacity(s.capacity),top(s.top) // 在stack 内部,可以通路其私有成員 //(以class封裝,而不是以對象來封裝
{
pstack = new T[capacity];
for (int i = 0; i < capacity; ++i)
{
pstack[i] = s.pstack[i];
}
cout << "stack copy" << endl;
}
// 移動拷貝構造函數
// 帶右值引用參數的拷貝構造函數 目的:把即将銷毀的記憶體保護起來,接着用
stack(stack<T>&& s) noexcept{
cout << "stack&&" << endl; /*此處沒有重新開辟記憶體拷貝資料,把s的資源直接給目前對象,再把s置空*/
capacity = s.capacity;
top = s.top;
pstack = s.pstack;
s.pstack = NULL; // 這裡剛剛寫錯了s=NULL導緻一直報錯
}
~stack() {
delete[] pstack;
cout << "stack delete" << endl;
}
// 重載=運算符
stack<T>& operator=(const stack<T>& s);
stack<T>& operator=(stack<T>&& s)noexcept;
T pop();
void push(T const& e);
int get_size();
// get_top表示獲得棧頂元素
T get_top();
void show();
};
template<typename T> stack<T>& stack<T>::operator=(stack<T>&& s)noexcept { // ERROR:operator函數重定義
if (&s == this)
return *this;
if (this != NULL)
delete[] pstack;
// 記憶體轉接
capacity = s.capacity;
top = s.top;
pstack = s.pstack;
s.pstack = NULL;
cout << "operator=&&" << endl;
return *this;
}
template<typename T> stack<T>& stack<T>::operator=(const stack<T>& s)
{
// 自身指派問題
if (&s == this) // 不能 s==*this,因為沒有重載等号運算符,兩個對象之間不能互相比較
return*this;
if (this != NULL)
delete[] pstack; // 釋放原有的空間記憶體
pstack = new T[s.capacity];
capacity = s.capacity;
top = s.top;
for (int i = 0; i < capacity; ++i)
{
pstack[i] = s.pstack[i];
}
cout << "stack operator=" << endl;
return *this;
}
template<typename T> int stack<T>::get_size()
{
return capacity;
}
template<typename T> T stack<T>::get_top()
{
return pstack[top];
}
template<typename T> void stack<T>::push(T const&e)
{
pstack[++top] = e;
size++;
}
template<typename T> T stack<T>::pop()
{
size--;
return pstack[top--];
}
template<typename T> void stack<T>::show()
{
for (int i = 0; i < size; ++i)
{
cout << pstack[i] << " ";
}
cout << endl;
}
// 以下為函數************************************************************************
template<typename T> stack<T> get_stack1(stack<T>& s) {
stack<T> temp(s.get_size());
return temp;
}
// 右值引用:引用臨時對象
template<typename T> stack<T> get_stack2(stack<T>&& s) {
stack<T> temp(s.get_size());
return temp;
}
int main()
{
stack<int> s;
s = get_stack1<int>(s);
// s = get_stack2<int>(s); //Error:沒有與參數清單比對的 函數模闆 "get_stack2" 執行個體,不能傳一個左值給右值引用
s.push(1);
s.push(3);
s.show();
s.pop();
s.show();
}