1、C++的std::string浅拷贝
这是帮朋友调适出来的一个错误,隐藏得很深,有些诡异。
全局指针 char* filename; 某函数中出现: function A() { std::string file = ;// 此处从其他地方获得文件名 filename = file.c_str(); // 将文件名复制后,然后到其他地方使用 // 这里错了!file是一个局部对象,当程序段离开这里后,file 就销毁了 // filename 指向 就指向了一片垃圾数据 } function B() { // 使用 filename } 如果两段代码在一个线程内,那么程序B处肯定会出现问题,因为filename指向的对象是垃圾数据。但如果,两段程序出现在两个不同的线程中,那么,表现出来的症状就不是这样了。
线程1: function A() { std::string file = ;// 此处从其他地方获得文件名 filename = file.c_str(); // 将文件名复制后,然后到其他地方使用 wxMessageBox("...message...");// 弹出一个对话框,阻塞这个线程 } 线程2: function B() { // 使用 filename } 倘若程序段B在关闭对话框之前取出 filename ,那么程序会执行正确;倘若程序段B在关闭对话框之后在取出filename,那么程序就会出现错误。也就是说,在加入了界面与线程以后,问题被隐藏的更深入了。因为它的表现具有一定的随机性,与你关闭对话框的动作相关。filename = file.c_str();是浅拷贝。数据区域并没有被拷贝。倘若将全局变量filename的类型设置为string,然后用filename = file做赋值操作,那么就不会出现这个问题了。因为这是一个深拷贝。
2.c++的std::string与Java的String 以前用Java String的时候,觉得这个类真的很好,屏蔽了太多的底层操作,用起来相当的方便,用c++的string觉得没这么方便了。简单的比较一下一些实现函数,发现c++串的功能并没有这么弱,只是平时用的太少了!
| C++ std::string | Java String |
创建字符串 | string s(“hehe”); string s=”hello”; | 类似 |
访问单个字符 | s[0] 不会进行范围检查 s.at(0) 会进行范围检查 | charAt(i)
|
字符串比较 | S1.compare(s2) 等于返回0,大于返回正数 | compareTo返回整型,>0表示大于,=表示等于 equals返回bool,true表示相等 == 比较两者引用是否相同,不比较内容 |
连接字符串 | S = s1+s2+s3; S = s1.append(s2); 只能连接string与char*类型,int,float等不行 | append() "+"号功能更强大,不仅能连接串,而且能连接 int,float等类型 |
字符串查找 | s.find(ss) | indexOf |
字符串替换 | s.replace(pos,search.size(),search) | replace |
提取字串 | s.substr(startpos,len) | substring |
删除与插入字串 | insert erase | delete insert |
其他 | string定义为typedef basic_string <char> string | 当字符串经常发生变化时,需要用StringBuffer替换String; |