1. 程式人生 > 其它 >侯捷c++課程 string類 筆記

侯捷c++課程 string類 筆記

class with pointer members

由於字串的長度是不確度的,所以使用陣列來存放字串,不好確定陣列大小
因此選擇使用char* 動態分配記憶體的方式來儲存

Big three 3個特殊函式

字串string類的資料成員只有一個char* 指標,通過動態分配記憶體指向字串
帶有指標的類有三個特殊函式 解構函式 複製建構函式 operator =

不能使用編譯器自動生成的operator =和複製建構函式,這些函式是直接的bit by bit 的指標賦值
會造成記憶體洩漏,即內容還在那裡,沒有被回收,但沒有指標指向這裡
同時會形成兩個指標指向同一塊記憶體區域,當一個指標delete後,另外一個也會受影響(alias)

複製建構函式和建構函式

首先獲取引數的字元長度,由於strlen返回的長度不包括結尾的'\0',所以要分配的記憶體空間要strlen(cstr)+1
在常規的建構函式中,即使指標引數為空指標,也要分配一個char的記憶體空間,內容為'\0'

inline
String::String(const char* cstr = 0)
{
    if (cstr)
    {
        m_data = new char[strlen(cstr) + 1];
        strcpy(m_data, cstr);
    }
    else
    {
        m_data = new char[1];
        *m_data = '\0';
    }
}

呼叫strcpy複製,自動複製結尾的'\0'

inline
String::String(const String& str)
{
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);
}

解構函式

當string類的例項物件的作用域結束後,os會收回其所佔用的記憶體空間
但string類的資料只有一個指標,這個指標所指向的內容是不會自動回收的,所以要在解構函式中手動delete

inline
String::~String()
{
    delete[] m_data;
}

operator =

實現和複製建構函式類似,但是要先清空自身內容,再進行賦值
要判定自我賦值的情況,如果不判斷,將直接清空自身的內容,指標成為野指標,會發生undefined behavior

inline
String& String::operator =(const String& str)
{
    if (this == &str)
        return *this;

    delete[] m_data;
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);
    return *this;
}

stack heap

在函式function body內宣告的變數,記憶體來自於stack
heap是os提供的一塊global記憶體空間,可通過new進行動態分配記憶體
stack object在作用域結束後被自動清理 而heap object仍然存在

static

在變數宣告前加static關鍵字,即為static object,其在作用域結束後仍然存在,直到整個程式結束
global object也可看作一種static object,作用域是整個程式

new delete

new被編譯器轉化為三個步驟:
1.呼叫malloc分配記憶體
2.static_cast型別轉換
3.呼叫建構函式

delete為兩個步驟:
1.呼叫解構函式
2.呼叫free釋放記憶體

array new 一定要搭配 array delete

delete 和 delete[] 都會將其所指的記憶體塊全部釋放
區別在於delete[]會對陣列內的每一個元素呼叫解構函式 而delete只對第一個元素呼叫
如果陣列元素為帶有指標成員的類,使用delete會造成memory leak