C/C++字串處理之String

來源:互聯網
上載者:User

Table of Contents

概要

理解String(BasicString)

關於TempString基類

源碼

參考閱 讀

概要

我們知道,C++標準庫(STL)提供了string(basic_string)類進行字串操作。字串很可能除了記憶體 分配器(allocator)1外使用最為頻繁的STL類。但是C++社區對string的指責從來就沒有停止過。

歸納起來,STL的 string類主要有以下這些爭議點:

介面過多且規格和其他STL容器沒有達成很好的一致性。例如,string::find使用下標 ,而不是以iterator作為迭代位置,這和其他容器不太一樣。

記憶體片段。由於過於頻繁的字串構造、析構,導致系統 的記憶體片段現象嚴重。

Copy -On-Write與多安全執行緒。string(basic_string)基於Copy-On-Write技術的原因,是因為 string的賦值被設計成為低開銷的。但是一旦考慮到多安全執行緒問題,Copy-On-Write會把大量的時間花在鎖的開銷上。一些新 的STL實現 (如SGI STL)放棄了基於Copy-On-Write的string實現。

我認同這些指責。字串最好的設計,還是將 string分拆為一個常字串(std::String)和一個字串操作類(StringBuilder)。我們的StdExt庫這樣做了。

理解 String(BasicString)

StdExt的String(BasicString),和你以前見過的所有字串類都不太一樣。這個類比你想象 的還要簡單,它只有兩個成員變數:

template <class _E>
class BasicString
{
    const _E* m_pszBuf;
    size_t m_length;
};

它區別於string(basic_string)之處在於:

它是一個常字串,它永遠不會試圖去篡改字串內容 (m_pszBuf指向的資料)。

它沒有析構,你可以認為其實只是一個結構體。當然,為了方便,BasicString還是有構造函 數。

它的m_pszBuf不以nil為結束。而是由m_length成員限定字串的長度。

它不維護字串內容(m_pszBuf) 的生命週期。如上所述,它沒有析構,任何時刻它只是接受或者產生字串內容,但是不負責銷毀它。

最後一點非常重 要,也是它的特別之處:它並不維護字串的生命週期。這可能讓你詫異:居然會有這樣字串類,它並不管理字串的生命周 期。

但是我們這樣做了。而這的確給我們帶來很多便利。例如:

賦值(複製)、子串(substr)是非常輕量的操 作。Copy-On-Write技術完全是多餘的。

可以將任意的線性容器(如std::vector、std::basic_string)臨時轉換為 String(非常輕量)。參見下文中對String::cast方法的介紹。

為什麼String類可以不管理自己的生命週期?這就是我 們StdExt的記憶體管理變革倡導的思想了。

瀏覽下String類的參考手冊,你注意到有這樣兩個建構函式:

BasicString(const value_type* pszVal, size_type cch);

template <class AllocT>
BasicString(AllocT& alloc, const value_type* pszVal, size_type cch);

這表示:第一個建構函式傳入 的pszVal,其生命週期比BasicString長(到BasicString析構時仍然有效)。而第二個建構函式的意思是,pszVal是一個臨時有 效的字串,這個建構函式將拷貝一個pszVal字串的副本。

為什麼不支援 BasicString(const value_type* pszVal) 這樣的構造?

很簡單,這個構造過於危險,我不能確定你的意圖是什麼。

關於TempString基類

從字面意 思來講,這是一個臨時字串類。為什麼它會是String(即BasicString)的基類?這其實只是實現上的需要。TempString理論 上就是String(只是有特殊的生命週期),和BasicString規格一致。之所以它最後成為BasicString的基類,完全是實現上方便 的考慮。

以BasicString::compare為例,我們考察以下這個函數:

int BasicString::compare(const TempString<_E> b) const;

這個函數的含義非常豐富。相當於定義了以下這一系列的函數:

int BasicString::compare(const _E& b) const; // 與包含單個字元b的字串比較
int BasicString::compare(const _E* b) const; // 與C Style風格的字串b比較
int BasicString::compare(const basic_string<_E>& b) const; // 與STL string比較
int BasicString::compare(const BasicString<_E>& b) const; // 與另一個常String比較
int BasicString::compare(const vector<_E>& b) const; // 與向量表示的字串b比較
int BasicString::compare(const BasicStringBuilder<_E>& b) const;

一個函數可抵6個函數!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.