在C語言中只能通過字符串數組來模擬字符串,沒有字符串類型。在C++引入了string類來表示字符串類型。從而用它定義字符串。
在C語言中:
char str[] = "abc";
char str[] = {'a','b','c','\0'};
char* str = "abc";
//這三種形式是C語言下用來表示字符串的方式。
而在C++語言下:
string str1;//調用無參構造,生成一個空字符串對象,strlen(str) = 0;
string str1 = "";//調用有參構造,雖然作用相當于上面的,生成一個空字符串對象。等價于string str1("");
string str2 = "abc";//調用有參構造
string str3("abc");//調用有參構造
string str4 = string("abc");//調用有參構造
string str5 = str4;//調用拷貝構造
string str6(str5);//調用拷貝構造
//以上這種方式都是定義字符串string類的對象。
注意
: “” 即空字符串也是一個字符串字面值,也會被存儲到靜態存儲區只存一份實例。
string類是基于模板的。是basic_string類的別名。
string類里有以下三個常用到的構造函數:
string(){_data = new char[1]; _data[0]='\0';};//無參構造
string(const char * str){//有參構造_data = new char[sizeof(str)];for(int i = 0; i < sizeof(str);i++){_data[i] = str[i];}
};
string(const string & str){//拷貝構造_data = new char[strlen(str)+1];strcpy(_data,str);
};
C++中的string類底層存儲字符串的原理是,存儲一個 char * 類型的成員指針變量(如上述構造函數中的_data)。
而 char * 類型的指針變量 會指向一塊堆內存。在堆內存中存儲字符串內容。當string類對象生命周期結束時,會調用 其析構函數,delete 掉 char *類型的指針變量。釋放存儲字符串內容的堆內存。
注意
:string對象中的字符串實際是存儲于堆內存中的。何時會釋放掉這塊堆內存,只要string類的對象的聲明周期結束即將時,它會自動調用string類的析構函數,來釋放成員變量_data所指向的那塊堆內存。
拷貝構造函數的調用機制,是必須根據當前已有的一個對象來對另一個新對象進行拷貝賦值。
下面說一下:
字符串的引用類型的使用
string & refstr = "abc";//編譯不過,“abc” 不是左值
const string & refstr = "abc";//可以,會根據string的有參構造函數生成一個匿名對象。然后refstr就是這個匿名對象的別。通過refstr來訪問匿名對象的地址。等價于 const string & refstr = string("abc");
如果想這個樣單獨的一條語句string("abc");//匿名對象,這一行表達式語句執行完畢后,string對象的生命周期就結束了。
那么像上面那樣 refstr可以延遲這個匿名對象生命周期。直到refstr引用變量的聲明周期結束后,那個匿名對象的聲明周期也就結束了。
void func(const string & refstr){............
}string str = "abc";
func(str);//這種方式傳參不存在對象創建。通過 refstr 來訪問 str內容。
func("abc");//這種方式傳參存在一次調用有參構造創建string類型的匿名對象。相等于func(string("abc"));通過refstr來訪問這個匿名對象。