您的位置:首页 > 其它

string 的实例分析。

2015-10-22 19:33 183 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/cplusren/article/details/49337721 // Last Update:2015-10-22 15:36:27
/**
 * @file str1.cpp
 * @brief  this is a test for string;
 * @author renzezhong
 * @version 0.1.00
 * @date 2015-10-22
 */
 /* 由于没有分析过string 的源代码,现在只描述现象,并作出个人推测,想细致了解的朋友可以自行查找string 源代码。
 *现象:
 *string 类使用有很多需要注意的地方,在一个项目中发现string 构造出现错误,使用的string 构造函数版本是string s((const) char* , (const)int , (const)int);( const 可能有也可能没有,个人认为有)
 *期望通过该构造函数将buf中length长度的内容拷贝到s中,但是由于buf中在某个位置(除了尾部)存在'\0'字符,导致buf中length个字节的内容并没有全部拷贝到s中,而是读到'\0'为止,造成内容的丢失。
 *其实现的效果等同与使用s.assign(cp)(cp是char *类型的指针)//用cp所指向的以空字符结束的字符串副本替换s.
 *
 *以下结合测试用例来推测...只是推测啊...但是现象还是可以看到的。
 */
#include <string>
#include <iostream>
using namespace std;
int main(void){
    char a [6]= {'0', '1', '2', '\0', '4', '5'};
    
    //版本一(推荐的版本):string (cp, n)   创建一个string对象,它被初始化为cp所指向数组的前n个元素的副本。注意这里说的是数组,数组和字符串有很大不同,就是数组中可以存储'\0'.
    cout << "string str(a, 6)" << endl;
    string str(a, 6);
    cout << str[4] << ' ' << str[5]<< endl;//4 5
    cout << str << endl;//01245

    //版本二(程序中出错的版本):string(const char *, int, int)这个版本的初始化在c++primer 中并没有出现过,但是可以使用不报错,个人推测是在string实例化时,调用了string s(string s2, int pos2, int len2) 版本//创建一个string对象,它被初始化为s2中从下标pos2开始的len2个字符的副本,如果pos2 > s2.size()则操作无效。 根据我所掌握的知识来推测,由于string被泛化过,所以string在实例化时有类似于模板实例化的隐式类型推断能力,具体来说:发现参数1是一个char*,而string 提供的三参构造函数中,没有对应版本,但是有一个三参版本中参数1是string,而string 有一个string s(const char* cp)的构造版本//创建一个string 对象,它被初始化为cp所指向的以空字符结束的字符串的副本,所以就调用这个构造函数先将参数一进行隐式类型转换,再调用版本2。 虽然参数3指定了要拷贝的长度,但是实际上只拷贝到buf中‘\0’前('\0'出现的位置在length指定的位置前),因此导致内容丢失。
    cout << "string str(a, 0, 6)" << endl;
    string str1(a, 0, 6);//效果等同于s.assign(cp)以cp所指向的以空字符结束的字符串副本替换s
    cout << str1[4] << ' ' << str1[5]<< endl;//4 5
    cout << str1 << endl;//01245
    
    
    //现在使用的版本:string (~::iterator p, ~:: iterator b, ~:: iterator e)//在迭代器p指向的元素之前插入迭代器b和迭代器e标记范围内所有的元素返回void.
    cout << "string str(str2.begin(), a, a+6)" << endl;
    string str2;
    str2.insert(str2.begin(), a, a+6);//在c++primer中并没有提供一个string(string::iterator p, char*, char*),但是考虑到迭代器底层封装的就是指针,所以推测进行了隐式类型转换也说的过去。
    cout << str2[4] << ' ' << str2[5]<< endl;//4 5
    cout << str2 << endl;//01245

}

/*
 *所以个人建议:不要轻易使用那些没有被明确定义过的版本,c++ primer 中列出的实例化方式非常多,相信够用...
 * */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: