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++串的功能并没有这么弱,只是平时用的太少了!
<o:p> </o:p>
|
C++ std::string<o:p></o:p>
|
Java String<o:p></o:p>
|
创建字符串<o:p></o:p>
|
string s(“hehe”);<o:p></o:p>
string s=”hello”;<o:p></o:p>
|
类似<o:p></o:p>
|
访问单个字符<o:p></o:p>
|
s[0] 不会进行范围检查<o:p></o:p>
s.at(0) 会进行范围检查<o:p></o:p>
|
charAt(i)<o:p></o:p>
<o:p> </o:p>
|
字符串比较<o:p></o:p>
|
S1.compare(s2)<o:p></o:p>
等于返回0,大于返回正数<o:p></o:p>
|
compareTo返回整型,>0表示大于,=表示等于<o:p></o:p>
equals返回bool,true表示相等<o:p></o:p>
== 比较两者引用是否相同,不比较内容<o:p></o:p>
|
连接字符串<o:p></o:p>
|
S = s1+s2+s3;<o:p></o:p>
S = s1.append(s2);
只能连接string与char*类型,int,float等不行
|
append()<o:p></o:p>
"+"号功能更强大,不仅能连接串,而且能连接 int,float等类型<o:p></o:p>
|
字符串查找<o:p></o:p>
|
s.find(ss) <o:p></o:p>
|
indexOf<o:p></o:p>
|
字符串替换<o:p></o:p>
|
s.replace(pos,search.size(),search)<o:p></o:p>
|
replace<o:p></o:p>
|
提取字串<o:p></o:p>
|
s.substr(startpos,len)<o:p></o:p>
|
substring<o:p></o:p>
|
删除与插入字串<o:p></o:p>
|
insert<o:p></o:p>
erase<o:p></o:p>
|
delete<o:p></o:p>
insert<o:p></o:p>
|
其他<o:p></o:p>
|
string定义为typedef basic_string <char> string<o:p></o:p>
|
当字符串经常发生变化时,需要用StringBuffer替换String;
|
分享到:
相关推荐
在C++编程中,类对象的深拷贝和浅拷贝是两个重要的概念,它们涉及到对象复制时内存管理的问题。当我们创建一个类的实例并将其赋值给另一个实例时,拷贝构造函数会被调用。拷贝构造函数是一种特殊的构造函数,它用于...
此外,通过赋值运算符`=`, 深拷贝和浅拷贝的概念也是字符串拷贝中的重要知识点。`字符串的拷贝.cpp`应该包含了如何进行字符串的拷贝以及如何避免常见的拷贝问题。 7. **字符串的替换操作**:`replace`函数允许我们...
详解C++中String类模拟实现以及深拷贝浅拷贝 在C语言中/C++中,字符串是一个应用很广泛的类型,也是很基础的类型,C语言并没有直接处理字符串的操作而是采用字符指针和字符串数组进行操作,而在C++中标准库为我们...
`std::string`还支持浅拷贝和深拷贝。 9. **流操作符`: `std::getline()`可以从输入流中读取一行,直到遇到换行符或文件结束。`和`>>`操作符可以方便地将字符串与输入/输出流结合使用。 10. **转换功能**: `to_...
2. **赋值与拷贝**:实现赋值运算符`=`和拷贝构造函数,确保深拷贝,避免浅拷贝导致的数据不一致问题。 3. **长度获取**:提供一个成员函数返回字符串的长度,如`size()`或`length()`。 4. **访问字符**:提供访问...
这需要考虑深拷贝和浅拷贝的问题,确保内存管理的正确性。 4. **拷贝构造函数**:处理对象的复制,确保每个对象都有自己独立的一份数据。 5. **输入/输出操作符**:重载`和`>>`运算符,使得可以方便地将字符串与...
此外,`std::string`的拷贝和赋值通常是浅拷贝,但在某些情况下会触发深拷贝,理解这一点有助于避免不必要的性能损失。 10. **字符串连接效率**:连续使用`+`运算符连接字符串可能导致多次内存分配和拷贝,效率较低...
深拷贝和浅拷贝是C++中处理对象复制时的两个关键概念,尤其在涉及到动态内存分配的情况。浅拷贝,也称为位拷贝,是指仅仅复制对象的成员变量的值,而不复制底层的资源。这意味着如果类的成员变量包含指针,那么新...
3. **拷贝构造函数和赋值运算符**:为了支持对象的复制,需要实现这两个特殊成员函数,确保深拷贝以防止浅拷贝导致的问题。 4. **析构函数**:释放分配的内存,确保良好的资源管理。 5. **操作符重载**:为了使得`...
这篇“C++字符串完全指南”深入浅出地介绍了C++中处理字符串的方法,是初学者不可多得的学习资源。下面我们将详细探讨C++中的字符串概念、字符串操作以及如何读取字符串。 1. **C++字符串基础** 在C++中,字符串是...
然而,对于包含动态分配资源的对象(如自定义的字符串类),浅拷贝仅仅复制对象的指针,而不复制指针所指向的数据。这意味着两个对象共享同一块内存,修改其中一个对象会影响另一个。这可能导致资源的重复释放或内存...
这被称为浅复制或赋值操作,它不仅复制了字符串的内容,还复制了所有相关属性,如字符串长度。如果原始字符串(这里是`str1`)之后被修改,复制后的字符串(`str2`)不会受到影响,因为它们各自都有独立的数据存储。...
- 当原始对象被销毁或改变时,浅拷贝的对象也会受到影响。 - **深拷贝**: - 深拷贝会复制对象的实际内容,而不是仅仅复制其引用。 - 深拷贝创建的是一个新的独立对象,与原对象互不影响。 #### 字符串 - **...
在C++中,当一个对象被复制时,默认执行的是浅拷贝,即创建了一个新对象,但这个新对象与原对象共享相同的资源,如指针成员。如果这些资源是动态分配的,这可能导致意外的结果,比如两个对象同时修改同一内存区域,...
9. **深拷贝与浅拷贝**:浅拷贝只复制对象的引用,而不复制底层资源。深拷贝会创建资源的新副本。当类中包含指针时,需要深拷贝防止数据丢失。 在实际编程中,理解并熟练掌握这些基本概念至关重要。对于初学者来说...
`std::string`支持直接赋值(`=`操作符)和拷贝构造函数,但要注意深拷贝和浅拷贝的区别。 8. **字符串流转换**: 可以使用`std::istringstream`和`std::ostringstream`进行字符串到流以及流到字符串的转换。 9....
深拷贝和浅拷贝是C++中拷贝构造函数和赋值操作符的重要概念。当我们创建一个新的对象并用已存在的对象初始化它时,就会调用拷贝构造函数。如果只是简单地复制对象的引用或指针(即浅拷贝),而不是复制底层的数据,...
书中会阐述构造链、深拷贝与浅拷贝、构造函数的异常安全性和智能指针在对象生命周期管理中的作用。 5. **继承与多态**:C++的继承机制允许创建类层次结构,而多态则是通过虚函数实现的。虚函数使得基类指针可以调用...
C++支持拷贝构造函数,用于创建一个新的对象作为现有对象的副本,同时涉及到深拷贝与浅拷贝的区别。this指针是一个特殊的指针,用于指向调用成员函数的对象本身。赋值运算符重载允许开发者定义对象间赋值行为。 在...