引言:又是有趣的一个知识点
一 开端
先上一段代码
class String
{
friend std::ostream& operator<<(std::ostream& stream,const String& string);
private:
char* m_buffer;
unsigned int m_size;
public:
String(const char* string){
m_size = strlen(string)+1;
m_buffer = new char[m_size];
memcpy(m_buffer,string,m_size);
}
~String(){
delete[] m_buffer;
}
};
std::ostream& operator<<(std::ostream& stream,const String& string)
{
stream<<string.m_buffer;
return stream;
}
int main(){
String s1 = "abc";
String s2 = s1;
std::cout<< s1<<endl;
std::cout<< s2<<endl;
return 0;
}
这里我们会看到以下一个现象:
1.输出两个 “abc”
2.发生异常
二 浅拷贝与深拷贝
上面的异常是因为 s1 和s2 在回收的时候执行析构函数时重复释放同一块内存导致。在执行 String s2 = s1 的时候,它会对 String 的成员变量m_buffer和m_size进行拷贝,m_size是值拷贝,而m_buffer是指针,s2 的m_buffer指向了和 s1 的 m_buffer同一块的内存地址。所以当我们回收内存的时候会出现这个异常。这就是浅拷贝了。那么我们要解决这个问题,就得使用深拷贝
class String{
friend std::ostream& operator<<(std::ostream& stream,const String& string);
private:
char* m_buffer;
unsigned int m_size;
public:
String(const char* string){
m_size = strlen(string);
m_buffer = new char[m_size+1];
memcpy(m_buffer,string,m_size+1);
}
String(const String& other):m_size(other.m_size)
{
std::cout<< "copy String"<<std::endl;
m_buffer = new char[m_size+1]; //创建一个新的m_buffer,然后进行拷贝
memcpy(m_buffer,other.m_buffer,m_size+1);
}
~String(){
delete[] m_buffer;
}
char& operator[](unsigned int index)
{
return m_buffer[index];
}
};
//这里两个 Print 方法看看会有什么不同哦
// void PrintString(String string){
// std::cout<<string <<endl;
// }
void PrintString(String& string){
std::cout<<string <<endl;
}
std::ostream& operator<<(std::ostream& stream,const String& string)
{
stream<<string.m_buffer;
return stream;
}
int main(){
String s1 = "abc";
String s2 = s1;
s2[2] ='d';
PrintString(s1);
PrintString(s2);
return 0;
}
输出日志
copy String
abc
abd