c++中,string是一个管理者,比如创建出一个string的对象后,这个对象是管理一个地方里面保存有字符串的,那么,创立了一个string后对象并初始化后,还能对它再赋值吗?如果再赋值是什么含义呢,是这个地方的字符串变换了吗(但是地址没有变),还是这一块地址里面依然有原来的字符串而这个string对象管理了另外一块地址的另外一个字符串呢?
比如说以下代码假设state.txt中是New York#New Mexico#Texas#Indiana
那么string city 就不断被赋值各个城市名称,这里面具体是如何实现的?
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main(){
ifstream input("state.txt");
if(input.fail())
{
cout<<"File does not exist"<<endl;
cout<<"Exit program"<<endl;
return 0;
}
string city;
while(!input.eof())
{
getline(input,city,'#');
cout<<city<<endl;
}
input.close();
cout << "Done" <<endl;
return 0;
}
string类中维护了三个指针:
_M_start为保存字符串的起始地址;_M_finish为终止地址;
_M_end_of_storage为string对象中当前申请空间的大小;
在第一次赋值后,_M_finish和_M_end_of_storage是一样大的(也可能不一样大,有的实现中考虑到对齐,一次可能会多分配几个字节)
在后续再赋值时:
1)如果新值的长度小于当前字符串的长度,使用memcpy直接拷贝;地址空间不变;
2)如果新值的长度大于当前当前字符串的长度,会申请一个新的空间,将新值拷贝过去,并释放原有空间;
string的c_str()方法返回的就是_M_start的值,将这个值打出来就知道地址是否变化:
写了一个示例,查看string的几个函数的返回值:
附上部分string源码:
参考:SGI STL的string的实现:
http://www.sgi.com/tech/stl/string