擴展——String類--構造字符串

構造字符串

程序清單16.1使用了string的7個構造函數(用ctor標識,這是傳統C++中構造函數的縮寫)。表16.1簡要的描述了這些構造函數。
使用構造函數時都進行了簡化,即隱藏了這樣一個事實:string實際上是模板具體化basic_string的一個typedef,同時省略了與內存管理相關的參數。
size_type是一個依賴於實現的整型,是在頭文件string中定義的。string類將string::npos定義爲字符串的最大長度,通常爲unsigned int的最大值。另外,表格中使用縮寫NBTS(null-terminated string)來表示以空字符結束的字符串——傳統的C字符串。
表16.1 string類的構造函數

構造函數 描述
*string(const char s) 將string對象初始化爲s指向的NBTS
string(size_type n,char c) 創建一個包含n個元素的string對象,其中每個元素都被初始化爲字符c
string(const string &str) 將一個string對象初始化爲string對象str(複製構造函數)
string() 創建一個默認的string對象,長度爲0(默認構造函數)
string(const char s,size_type n) 將string對象初始化爲s指向的NBTS的前n個字符,即使超過了NBTS結尾
template<class Iter> string(Iter begin,Iter end) 將string對象初始化爲區間[begin,end)內的字符,其中begin和end的行爲就像指針,用於指定位置,範圍包括begin在內,但不包括end
string(const string & str,string size_type pos=0,size_type n=npos) 將一個string對象初始化爲對象str中從位置pos開始到結尾的字符,或從位置pos開始的n個字符
string(string &&str)noexcept 這是C++11新增的,它將一個string對象初始化爲string對象str,並可能修改str(移動構造函數)
string(initializer_list<char>il 這是C++11新增的,它將一個string對象初始化爲初始化列表il中的字符

程序清單16.1 str1.cpp

//str1.cpp -- introducing the string class
#include<iostream>
#include<string>
//using string constructors

int main()
{
	using namespace std;
	string one("Lottery Winner!");	//ctor #1
	cout << one << endl;			//overloaded<<
	string two(20, '$');			//ctor #2
	cout << two << endl;
	string three(one);				//ctor #3
	cout << three << endl;
	one += "Oops!";					//overloaded +=
	cout << one << endl;	
	two = "Sorry! That was ";
	three[0] = 'P';
	string four;					//ctor #4
	four = two + three;				//overloaded + ,=
	cout << four << endl;
	char alls[] = "All's well that ends well";
	string five(alls, 20);			//ctor #5
	cout << five << "!\n";
	string six(alls + 6, alls + 10);	//ctor #6
	cout << six << ", ";
	string seven(&five[6], &five[10]);	//ctor #6 again
	cout << seven << "...\n";
	string eight(four, 7, 16);			//ctor #7
	cout << eight << " in motion!" << endl;
	return 0;
}

下面是程序的輸出:
在這裏插入圖片描述

1. 程序說明

程序清單16.1的程序首先演示了可以將string對象初始化爲常規的C-風格字符串,然後使用重載的<<運算符來顯示它:

string one(“Lottery Winner!”);		//ctor #1
cout<<one<<endl;				//overloaded <<

接下來的構造函數將string對象two初始化爲由20個$字符組成的字符串:

string two(20,’$’);					//ctor #2

複製構造函數將string對象three初始化爲string對象one:

string three(one);					//ctor #3

重載的+=運算符將字符串“Oops!”附加到字符串one的後面:

one += “ Oops!”;					//overloaded +=

這裏是將一個C-風格字符串附加到一個string對象的後面。但+=運算符被多次重載,以便能夠附加string對象和單個字符:

one += two;		//append a string object (not in program)
one += ‘!’;		//append a type char value (not in program)

同樣,=運算符也被重載,以便可以將string對象,C-風格字符串或char值賦給string對象:

two = “Sorry! That was “;		//assign a C-style string
two = one;					//assign a string object (not in program)
two = ‘?’;						//assign a char value (not in program)

重載[ ]運算符使得可以使用數組表示法來訪問string對象中的各個字符:

three[0] = ‘P’;

默認構造函數創建一個後可對其進行賦值的空字符串:

string four;					//ctor #4
four = two + three;			//overloaded +, =

第2行使用重載的+運算符創建了一個臨時string對象,然後使用重載的=運算符將它賦給對象four。正如所預料的,+運算符將其兩個操作數組合成一個string對象。該運算符被多次重載,以便第二個操作數可以是string對象,C-風格字符串或char值。

第5個構造函數將一個C-風格字符串和一個整數作爲參數,其中的整數參數表示要複製多少個字符:

char alls[ ] = “All’s well that ends well”;
string five(all, 20);			//ctor #5

從輸出可知,這裏只使用了前20個字符(”All’s well that ends”)來初始化five對象。正如表16.1指出的,如果字符數超過了C-風格字符串的長度,仍將複製請求數目的字符。所以在上面的例子中,如果用40代替20,將導致15個無用字符被複制到five的結尾處(即構造函數將內存中位於字符串”All’s well that ends well”後面的內容作爲字符)。

第6個構造函數有一個模板參數:

template<class Iter>string(Iter begin, Iter end);

begin和end將像指針那樣,指向內存中兩個位置。構造函數將使用begin和end指向的位置之間的值,對string對象進行初始化。[begin,end)來自數學中,意味着包括begin,但不包括end在內的區間。也就是說,end指向被使用的最後一個值後面的一個位置。請看下面語句:
string six(alls+6,alls+10); //ctor #6
由於數組名相當於指針,所以alls+6和alls+10的類型都是char*,因此使用模板時,將用類型char*替換Iter。第一個參數指向數組alls中的第一個w,第二個參數指向第一個well後面的空格。因此,six將被初始化爲字符串“well”。

現在假設要用這個構造函數將對象初始化爲另一個string對象(假設爲five)的一部分內容,則下面的語句不管用:

string seven(five+6,five+10);

原因在於,對象名(不同於數組名)不會被看作是對象的地址,因此five不是指針,所以five+6是沒有意義的。然而,five[6]是一個char值,所以&five[6]是一個地址,因此可被用作該構造函數的一個參數。

string seven (&five[6],&five[10]);		//ctor #6 again

 第7個構造函數將一個string對象的部分內容複製到構造的對象中: string eight(four,7,16);

上述語句從four的第8個字符(位置7)開始,將16個字符複製到eight中。

2.C++11新增的構造函數

構造函數string(string && str)類似於複製構造函數,導致新創建的string爲str的副本。但與複製構造函數不同的是,它不保證將str視爲const。這種構造函數被稱爲移動構造函數(move constructor)。
構造函數string(initializer_listil)讓您能夠將列表初始化語法用於string類。也就是說,它使得下面這樣的聲明是合法的:
string piano_man = {‘L’,’I’,’s’,’z’,’t’};
string comp_lang {‘L’, ‘I’, ‘s’, ‘p’};

就string而言,這可能用處不大,因爲使用C-風格字符串更容易,但確實實現了讓列表初始化語法普遍使用的意圖。

From 《C++ Primer Plus》
By Suki

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章