任务:
(《C++ Primer 4th》习题5.18)编写程序定义一个vector对象,其每个元素都是指向string类型的指针,读取该vector对象,输出每个string的内容及其相应的长度。
自己的方法:
string s;
string sarr[10];
//vector内的每个元素都是指向string类型的指针,这样定义vector
vector<string *> pvec;
cout<<"please enter some character strings."<<endl;
for(size_t i = 0;i != 10 ; ++i)
cin >> sarr[i];
for(string *p = sarr ; p != sarr+10; ++p)
pvec.push_back(p);
for(vector<string *>::iterator ix = pvec.begin(); ix != pvec.end(); ++ix)
{
cout<<**ix<<" "<<(**ix).size()<<" "<<endl;
}
cout<<endl;
这种方法定义了一个string数组,缺点是明显的,即数组一旦定义大小就不能改。
答案方法:
string s;
vector<string *> psvec;
cout<<"please enter some character strings."<<endl;
while(cin>>s)
{
//这里为什么要用new,有分析
string *p = new string;
*p = s;
psvec.push_back(p);
}
for(vector<string *>::iterator iter = psvec.begin() ; iter != psvec.end() ; ++iter)
cout<<**iter<<" "<<(**iter).size()<<endl;
for(vector<string *>::iterator iter = psvec.begin() ; iter != psvec.end() ; ++iter)
delete *iter
结果:输入my name is zhao lei,运行结果为:
分析读取vector对象时为什么要用new:
如果把答案中读取vector对象的部分写成:
while(cin>>str)
{
string *pstr;
pstr = &str ;
psvec.push_back(pstr);
}
输入my name is zhao lei。则输出结果如下,即将最后一个字符输出了psvec.size()次。
分析原因:string *pstr ;pstr = &str ;这两个语句的作用是定义了一个野指针pstr,然后把str的地址赋给了它。然而str在内存中只有一块地址,在每一次读取数据的时候是不断被赋值改变的,所以每一次str的内容都被下一次的内容覆盖,最后的结果就是所有的指针都指向了同一个str,且str中的内容为最后一个string对象,这就是出现上述结果的原因。
而答案中的方法,每一次从输入缓存中读取数据的时候都用string *p = new string;这个语句为指针p开辟了一段内存空间,然后将输入的值赋给该指针所指向的内存单元。最终的结果是,输入了多少个string对象就有多少个指针,且每个指针指向定义时为自己开辟的内存单元,因此vector中保存的是指向每个string对象的指针。因此必须采用答案中的方法。