復習一下數據結構,用鏈表實現了一個堆棧模板類。
寫的過程中用到一些知識點,碰到一些問題,隨手記下來。
1:mystack<int> s; mystack<int> s2 = s;
編譯器會把s2 = s編譯成拷貝構造函數s2(s),此時調用的是拷貝構造函數,而不是賦值函數(切記)。
另外有時候編譯器這種自做聰明,自動調用符合參數類型的構造函數會帶來很難發現的錯誤,為了防止編譯器這么做,可以在構造函數聲明前加explicit關鍵字。
2:不改變成員變量值的函數,例如empty(),要聲明為const,這點很重要,不然當一個const mystack&類型的對象調用empty()的時候,會編不過。
3:拷貝構造函數最好要先判斷是否是拷貝自身,不然有時候就出錯。
4:拷貝構造函數也別忘了成員變量初始化列表。
template<typename T>
class mystack

{
public:
mystack();
mystack(const mystack& src);
~mystack();
bool push(const T& data);
T pop();
bool empty() const;
void clear();
mystack& operator = (const mystack& src);
private:
void copystack(mystack& dst, const mystack& src);
struct stacknode
{
T data;
stacknode* pnext;
};
stacknode* phead;
};
template<typename T>
mystack<T>::mystack():phead(NULL)

{}
template<typename T>
mystack<T>::mystack(const mystack<T>& src):
phead(NULL)

{
copystack(*this, src);
}
template<typename T>
mystack<T>::~mystack()

{
clear();
}
template<typename T>
void mystack<T>::clear()

{
while(!empty())
{
pop();
}
}
template<typename T>
void mystack<T>::copystack(mystack& dst, const mystack& src)

{
stacknode* p = src.phead;
mystack<T> tmp;
while(p)
{
tmp.push(p->data);
p = p->pnext;
}
while(!tmp.empty())
{
dst.push(tmp.pop());
}
}
template<typename T>
mystack<T>& mystack<T>::operator=(const mystack& src)

{
if (this == &src)
return *this;
clear();
copystack(*this, src);
return *this;
}
template<typename T>
bool mystack<T>::empty() const 

{
return(phead == NULL);
}
template<typename T>
bool mystack<T>::push(const T& data)

{
stacknode* p = new stacknode;
if (!p) return false;
p->data = data;
p->pnext = phead;
phead = p;
return true;
}
template<typename T>
T mystack<T>::pop()

{
assert(!empty());
T data;
data = phead->data;
stacknode* tmp = phead;
phead = phead->pnext;
delete tmp;
return data;
}
int main(int argc, char* argv[])

{
mystack<int> s;
for (int i = 0; i < 1000; i++)
s.push(rand());
mystack<int> s2(s);
while(!s2.empty())
{
cout<<s2.pop()<<endl;
}
return 0;
}

