class T
{
};
main()
{
T tObj;
T *tObj = new T;
T tObj = T();
}
不管怎麼宣告一個物件,都會去 call 該類別的建構式,有時我們沒寫建構式,用的就是 C++ 預設的建構式,包括無參數的建構式 T::T(),另外一個常常被乎略的就是 copy constructor 為 T::T(const &T)
copy constructor 也是預設會自動產生的,所以你才有辦法這麼做
T tObj;
tObj.m_ID = 1;
T tNewObj = T(tObj);
預設的 copy constructor 會幫你把兩個物件內的各成員一個一個用 = 相接,這就叫無腦複製,竟然如此,這時後要特別注意類別內是否有指標成員,例如
class T
{
int m_nID;
TCHAR *m_strName;
~T()
{
if(m_strName)
{
free(m_strName);
m_strName = NULL;
}
}
};
T *tObj = new T;
tObj->m_strName = "Ascii";
T tNewObj = T(*tObj);
delete tObj;
之後如果你使用 tNewObj.m_strName 將會發生無可預期的錯誤,因為 tObj 與 tNewObj 的 m_strName 是同一個,但 tObj 已經解構了,m_strName 已經被指向 NULL 了,而 0 是不可取用的位址。
所以當你的類別有指標成員變數,請記得自己寫 copy constructor 以此為例
T::T(const T &refT)
{
this->m_nID = refT.m_nID;
this->m_strName = (TCHAR*)malloc(sizeof(TCHAR) * (lstrlen(refT.m_strName) + 1));
// 記憶體空間 + 1 是因為這個成員是字串,需要結束字元 \0
_tcscpy(this->m_strName , refT.m_strName);
}
若會用到 = 來相等兩個物件,也要記得覆寫 =
T& operator=(const T &refT)
{
this->m_nID = refT.m_nID;
this->m_strName = (TCHAR*)malloc(sizeof(TCHAR) * (lstrlen(refT.m_strName) + 1));
_tcscpy(this->m_strName , refT.m_strName);
return *this;
}
除此之外需注意的,不只建構式會預設自動產生,有些 function 也是會預設產生的,例如
operator= // 指定運算子
operator& // 取址運算子
沒有留言:
張貼留言